我有一个 NextJs 13 项目,需要 API 来处理发送给它的文件。我已经使用 formidable 来处理中间件
我的 app/api/uploadfile/route.ts 文件(代码已最小化以便集中)
import { IncomingForm } from "formidable";
export const config = {
api: {
bodyParser: false
}
};
const asyncParse = (req:any) =>
new Promise((resolve, reject) => {
const form = new IncomingForm({ multiples: true });
form.parse(req, (err, fields, files) => {
if (err) return reject(err);
resolve({ fields, files });
});
});
export async function PUT(req:any, res:any) {
console.log("Receiving");
if (req.method === "PUT") {
const result = await asyncParse(req);
res.status(200).json({ result });
}
}
这里我通过 postman 使用端点 localhost:3000/api/uploadfile 调用 api
我收到错误
error - TypeError: req.on is not a function
at IncomingForm.parse (webpack-internal:///(sc_server)/./node_modules/formidable/lib/incoming_form.js:90:9)
at eval (webpack-internal:///(sc_server)/./app/api/uploadfile/route.ts:18:14)
at new Promise (<anonymous>)
at asyncParse (webpack-internal:///(sc_server)/./app/api/uploadfile/route.ts:14:27)
at PUT (webpack-internal:///(sc_server)/./app/api/uploadfile/route.ts:29:30)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:219:24)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:92:36)
at NoopContextManager.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:360:30)
at ContextAPI.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:30:58)
at NoopTracer.startActiveSpan (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:953:34)
at ProxyTracer.startActiveSpan (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:993:36)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:81:107)
at NoopContextManager.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:360:30)
at ContextAPI.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:30:58)
at NextTracerImpl.trace (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:81:32)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:214:49)
at AsyncLocalStorage.run (node:async_hooks:345:14)
at Object.wrap (webpack-internal:///(sc_server)/./node_modules/next/dist/server/async-storage/static-generation-async-storage-wrapper.js:32:24)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:171:93)
at AsyncLocalStorage.run (node:async_hooks:345:14)
at Object.wrap (webpack-internal:///(sc_server)/./node_modules/next/dist/server/async-storage/request-async-storage-wrapper.js:59:24)
at AppRouteRouteModule.execute (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:170:87)
at AppRouteRouteModule.handle (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:259:41)
at RouteHandlerManager.handle (E:\Projects\Templates\backend-template\node_modules\next\dist\server\future\route-handler-managers\route-handler-manager.js:22:29)
at doRender (E:\Projects\Templates\backend-template\node_modules\next\dist\server\base-server.js:848:58)
at cacheEntry1.responseCache.get.incrementalCache.incrementalCache (E:\Projects\Templates\backend-template\node_modules\next\dist\server\base-server.js:1059:34)
at E:\Projects\Templates\backend-template\node_modules\next\dist\server\response-cache\index.js:83:42
at ResponseCache.get (E:\Projects\Templates\backend-template\node_modules\next\dist\server\response-cache\index.js:131:11)
at DevServer.renderToResponseWithComponentsImpl (E:\Projects\Templates\backend-template\node_modules\next\dist\server\base-server.js:978:54)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
我尝试过的事情
我的最终目标
我想在我的ckeditor5实现中使用这个API端点(作为图像上传适配器)
看起来我们不需要使用 Nextjs 进行强大的、多方的或多方的操作,因为它可以处理这个问题。如果您遇到类似问题,请尝试此操作。 https://github.com/vercel/next.js/issues/48875#issuecomment-1592301037
我通过将 api 移至页面文件夹 (pages/api/uploadfile.ts) 来修复此问题,无需更改任何代码。
我发现这是使其发挥作用的唯一方法。我猜发生的情况是应用程序目录中的 api 无法被邮递员等外部应用程序访问,但我不完全确定。
你不再需要强大的力量。 Next.js 13 在其应用程序中添加了一个新功能
formData();
来处理文件上传,并限制了处理此功能的 formidable 的使用。所以就是这样(我正在回答你的目标:使用 CKEditor5 来处理这个问题。也可以使用邮递员):
const formData = await request.formData();
const file: any = formData.get("upload");
对我来说,我需要将文件上传到cloudinary,所以这就是我解决它的方法。
const formData = await request.formData();
const file: any = formData.get("upload");
const arrayBuffer = await file.arrayBuffer();
const buffer = new Uint8Array(arrayBuffer);
let uploadedImageUrl: any = await new Promise((resolve, reject) => {
cloudinary.uploader
.upload_stream({}, function (error, result: any) {
if (error) {
reject(error);
return;
}
resolve(result);
})
.end(buffer);
});
如果您
console.log(result)
,您将看到文件的返回值。返回 secure_url,它将把图像返回到编辑器中。