如何使用formidable配合NextJS 13 API进行图片上传并解决请求错误?

问题描述 投票:0回答:1

我正在尝试向我的应用程序添加图像上传功能。 我正在使用 NextJS 13.4.4 和 formidable@v3。每当我上传图像时,我都会收到此错误:

错误 TypeError:req.on 不是函数 在 IncomingForm.parse (webpack-internal:///(sc_server)/./node_modules/formidable/src/Formidable.js:182:13)

注意:此代码适用于 next13 之前的版本。

我有一个简单的表格:

"use client";
import React, { useState } from "react";
import Image from "next/image";
import axios from "axios";

type Props = {};

export default function page({}: Props) {
  const [uploading, setUoploading] = useState(false);
  const [selectedImage, setSelectedImage] = useState("");
  const [selectedFile, setSelectedFile] = useState<File>();
  return (
    <div className="max-w-4xl mx-auto p-20 space-y-6">
      <label>
        <input
          type="file"
          hidden
          onChange={({ target }) => {
            if (target.files) {
              const file = target.files[0];
              setSelectedImage(URL.createObjectURL(file));
              setSelectedFile(file);
            }
          }}
        />
        <div className="w-40 aspect-video rounded flex items-center justify-center border-2 border-dashed cursor-pointer">
          {selectedImage ? (
            <Image src={selectedImage} alt="" width={160} height={90} />
          ) : (
            <span>Select Image</span>
          )}
        </div>
      </label>
      <button
        onClick={handleUpload}
        disabled={uploading}
        style={{ opacity: uploading ? ".5" : "1" }}
        className="bg-red-400 p-3 w-32 text-center rounded text-white"
      >
        {uploading ? "Uploading..." : "Upload"}
      </button>
    </div>
  );

  async function handleUpload() {
    setUoploading(true);
    try {
      if (!selectedFile) {
        return;
      }
      const formData = new FormData();
      formData.append("myImage", selectedFile);
      const data = await axios.post("/api/upload", formData);
      console.log(data);
    } catch (error: any) {
      console.log(error);
    }
    setUoploading(false);
  }
}

以及API后端代码:

import formidable from "formidable";
import { NextApiRequest } from "next";
import path from "path";
import fs from "node:fs/promises";

export const config = {
  api: {
    bodyParser: false,
  },
};

async function readFile(
  req: NextApiRequest,
  saveLocally?: boolean
): Promise<{ fields: formidable.Fields; files: formidable.Files }> {
  const options: formidable.Options = {};
  if (saveLocally) {
    options.uploadDir = path.join(process.cwd(), "/public/");
    options.filename = (name, ext, path, form) => {
      return `${Date.now().toString()}_${path.originalFilename}`;
    };
  }
  const form = formidable(options);
  return new Promise((resolve, reject) => {
    form.parse(req, (err, fields, files) => {
      if (err) reject(err);
      resolve({ fields, files });
    });
  });
}

export async function POST(req: NextApiRequest) {
  try {
    await fs.readdir(path.join(process.cwd(), "/public"));
  } catch (error) {
    await fs.mkdir(path.join(process.cwd(), "/public"));
  }
  await readFile(req, true);
  return new Response(JSON.stringify({ done: "ok" }));
}

我从这里获取了此代码。 我需要帮助弄清楚在新的下一个版本中要更改哪些内容。

javascript next.js formidable next-api
1个回答
0
投票

这不是答案,我只是想知道你是否解决了这个问题,因为我也有同样的问题

© www.soinside.com 2019 - 2024. All rights reserved.