fullstack-matters-next-全栈框架搭建过程中遇到的问题记录
config
Image
⚠ The “images.domains” configuration is deprecated. Please use “images.remotePatterns” configuration instead.
const config = { webpack: (config, { isServer }) => { },
images: { remotePatterns: [ { protocol: "https", hostname: "**" }, { protocol: "https", hostname: "xxx.com" }, ],
}, };
|
next-auth
google-timeout
GoogleProvider({ clientId: env.GOOGLE_ID, clientSecret: env.GOOGLE_SECRET, httpOptions: { timeout: 40000, }, }),
|
[next-auth][error][SIGNIN_OAUTH_ERROR] https://next-auth.js.org/errors#signin_oauth_error outgoing request timed out after 3500ms { error: { message: 'outgoing request timed out after 3500ms', stack: 'RPError: outgoing request timed out after 3500ms\n' + ' at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/openid-client@5.6.5/node_modules/openid-client/lib/helpers/request.js:140:13)\n' + ... ' at async Server.requestListener (D:\\Repos\\AI-MOBI\\Dress\\ChatUp-AI-Dress-fullstack\\node_modules\\.pnpm\\next@14.2.5_react-dom@18.3.1_react@18.3.1__react@18.3.1\\node_modules\\next\\dist\\server\\lib\\start-server.js:141:13)', name: 'RPError' }, providerId: 'google', message: 'outgoing request timed out after 3500ms' }
https://next-auth.js.org/errors#signin_oauth_error { error: { message: '', stack: 'AggregateError\n' + ' at internalConnectMultiple (node:net:1114:18)\n' + ' at afterConnectMultiple (node:net:1667:5)\n' + ' at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)', name: 'AggregateError' }, providerId: 'google', message: '' }
|
这是因为 auth 走的是后端而不是前端浏览器, next dev 跑的服务没走网络代理, 打开 tun 模式就行了
secret-missing
Please define a secret
in production
providers: [ GoogleProvider({ clientId: env.GOOGLE_ID, clientSecret: env.GOOGLE_SECRET, httpOptions: { timeout: 40000, }, }), ],
secret: env.NEXTAUTH_SECRET,
|
prisma
client-deps-error
Prisma Client was generated for “linux-musl-openssl-3.0.x”, but the actual deployment required “debian-openssl-3.0.x”
如下加上 [3]
generator client { provider = "prisma-client-js" binaryTargets = ["native", "debian-openssl-3.0.x"] }
|
table-does-not-exist
The table main.account
does not exist in the current database.
类似的问题先直接试一下 prisma db push
更新下数据库结构
nextauth-mysql
Try signing in with a different account.
next auth google login failed | prisma | mysql
非常坑的问题, 说是无法登录, 实际是无法在 db 中插入数据, 务必删库重新建一个试试!!
too-lang
NextAuth With Prisma for mysql specified key is too long
字段加上 @db.Text
usage
文件上传-upload-file-image
如何实现图片/文件上传操作
使用 t3app 创建的项目, 其中用到了 tRPC, 但很难受的是它对文件传输不支持
只能用 next 原生 API router 去写 RESTFUL [1]
next 后端如何解析 form 格式带文件的请求
一开始是想用 form 直接上传图片文件, 但是解析过程中有问题 (用到的是 formidable )
不知道哪里的问题, 解析出来的文件会在 fields 里 (string 形式, 很奇怪), files 为空
export const config = { api: { bodyParser: false, }, };
function parseForm( req: NextApiRequest ): Promise<{ fields: Fields; files: Files }> { return new Promise((resolve, reject) => { const form = new IncomingForm({ allowEmptyFiles: true, multiples: true, maxFileSize: 50 * 1024 * 1024, });
form.parse(req, (err, fields, files) => { if (err) { reject(err); } else { resolve({ fields, files }); } }); }); }
|
image-to-Buffer2string
转为使用 string 去传递图片
前端, 先从事件拿到 File 对象, 转为 ArrayBuffer, 再转为 binary 格式的 Buffer
const handleImageChange = (event: React.ChangeEvent<HTMLInputElement>) => { const file = event.target.files?.[0]; if (!file) return;
file .arrayBuffer() .then((data) => { const textData = Buffer.from(data).toString("binary");
|
后端:
interface ResData { file: string; }
export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method !== "POST") { return res.status(405).json({ error: "Method not allowed" }); }
try { const data = JSON.parse(req.body as string) as ResData;
const buffer = Buffer.from(data.file, "binary");
return res.status(200).json({ status: "ok" }); } catch (err) { console.error(err); return res.status(500).json({ error: "Error parsing form data" }); } }
|
next-router-多页面路由
使用 t3app 创建的项目一般会带有 layout.tsx 和 page.tsx, 作用是这样:
- app - layout.tsx // 控制网站根节点页面布局 - page.tsx // 控制 '/' 页面路由 - login // 新建 '/login' 页面 - layout.tsx// 同理, 根节点必须有, 子页面没有也行 - page.tsx // 同理, 子页面必须 - about // 新建 '/about' 页面 - page.tsx
|
可以新建这个文件, 然后访问 /login
试一试
export default function Page() { return <h1>Hello, login page!</h1>; }
|
payment-stripe
No such price: ‘price_1PyqB006uMozVQ0qomnghCIo’; a similar object exists in live mode, but a test mode key was used to make this request.
priceId 与 stripe secret 不匹配导致, 正式与测试key 不通用
deployments
vercel-file-read-write
用了之后才深刻知道 vercel 是个 serverless 平台, 也就是代码里不能用 “fs”
当然也不是完全不能用, 是只读状态 (申请写入会报错: EROFS: read-only file system
)
文件引入也比较苛刻 (通过 ../
这种导入很容易出现 file not found) [2]
按官方建议 是这种:
path.join(process.cwd(), "/public/img/xxx.png");
|
如果真遇到需要 临时
写入的情况, 可以用 /tmp
这个路径
vercel read-only file system, chmod
另外更建议的做法是用 Buffer 传递, 一般主流第三方库的输入输入都适配了 (比如我用到了 Jimp)
Jimp-watermark-添加水印
const srcImg = await Jimp.read( Buffer.from(await(await fetch(data.output.image_url ?? "")).arrayBuffer()) );
srcImg.composite( await Jimp.read(path.join(process.cwd(), "/public/img/watermark.png")), 10, srcImg.getHeight() - 100, { mode: Jimp.BLEND_SOURCE_OVER, opacitySource: 1, opacityDest: 0.8, } );
const resultBuffer = await srcImg.getBufferAsync(Jimp.MIME_JPEG);
|
aliyun-百炼换装
Download the media resource timed out during the data inspection process.
这问题是由于资源链接离上海有点远/太大, 获取超时了, 把文件服务换到 ap-shanghai
centos7-宝塔-docker-CICD
首先面临的问题是 centos 7 在不升级系统的情况下无法直接安装 nodejs 18 (nextjs 最低要求)
所以选择用 docker 部署, t3app 自带了 Dockerfile,
借物表
[1]: https://stackoverflow.com/questions/76105855/send-blob-image-from-frontend-to-backend-with-nextjs-and-trpc-t3-stack
[2]: How to Read and Write Files in Next.js on a Vercel Deployed Website
[3]: MissingSecret [MissingSecretError]: Please define a secret
in production