Как использовать Formidable с API NextJS 13 для загрузки изображений и устранения ошибки запроса?

Я пытаюсь добавить в свое приложение функцию загрузки изображений. Я использую 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" }));
}

Этот код я взял отсюда . Мне нужна помощь, чтобы выяснить, что изменить в следующей версии.

0 ответов

Другие вопросы по тегам