使用 Remix.run 上传文件:文件对象在操作中变成字符串

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

我正在开发一个 Remix 应用程序,用户可以通过表单上传文件。我有一个用于表单提交的处理程序函数,它获取表单数据(包括文件附件)并将其发布到我的操作中。

问题是,当我在操作中接收文件时,它似乎是作为字符串而不是 File 对象或 Blob 接收的。当我使用 value instanceof File 检查传入对象是否是 File 的实例时,它返回 false。

这是我提交的句柄:

 const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
        const requiredFields = [
            "projectName",
            "blockchain",
            "supply",
            "mintPrice",
            "mintDate",
            "twitterLink",
            "emailContact",
            "description",
            "teamSummary",
            "teamMembers",
            "references",
            "documents",
            "artwork",
            "marketing",
            "allowlist",
            "investment",
        ];
    const newErrors = {...initialErrors};
    let $form = event.currentTarget;
    let formData = new FormData($form);

    requiredFields.forEach(field => {
        if (!projectForm[field as keyof ProjectFormState]) {
            newErrors[field] = true;
        }
    });

    if (Object.values(newErrors).some(value => value)) {
        setErrors(newErrors);
        return;
    }

    console.log('projectForm', projectForm);

    Object.entries(projectForm).forEach(([key, value]) => {
        console.log('file type in submit', value instanceof File)
        if (value instanceof File) {
            console.log('file value', value)
            formData.append(key, value, value.name);
        } else {
            formData.set(key, value);
        }
    });

    submit(formData, {
        method: $form.getAttribute("method") as HTMLFormMethod ?? $form.method,
        action: $form.getAttribute("action") ?? $form.action,
    });
};

这里调用文件值日志,但是在我的操作中:

export const action = async ({request}: ActionArgs) => {
const formData = await request.formData();
const project: ProjectFormFields = {} as ProjectFormFields;

await Promise.all(Array.from(formData.entries()).map(async ([key, value]) => {
    console.log(key, value); // Log the value of 'value'
    console.log(value instanceof File); // Check whether 'value' is a File instance
    if (value instanceof File) {
        const arrayBuffer = await value.arrayBuffer();
        project[key] = Buffer.from(arrayBuffer);
    } else {
        project[key] = value;
    }
}));

console.log(project)

try {
    const response = await putProjectForm(project);
    const {status} = response;
    console.log('Form submission response', status);

    return redirect("/", {
        headers: {
            "Set-Cookie": `message=Your form was submitted successfully; Path=/;`,
        },
    });

} catch(error) {
    console.error('There was an error with the form submission', error);
}

return null;

}

console.log(value instanceof File);
返回 false。我不确定它是否如何将文件附加到表单数据上。但任何帮助都将是巨大的!谢谢!

javascript reactjs typescript forms form-data
1个回答
0
投票

您可以使用“multer”包将文件存储在您的文件夹之一中,然后只需将网址保存在数据库中。

const multer = require("multer");
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "./public/images/");
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
    cb(null, file.fieldname + '-' + uniqueSuffix)
  },
});
const fileFilter = (req, file, cb) => {
  file.mimetype === "image/png" ||
  file.mimetype === "image/jpg" ||
  file.mimetype === "image/jpeg"
    ? cb(null, true)
    : cb(null, false);
};
app.use(multer({ storage, fileFilter }).single("image"));

你可以在 server.js 中使用这个快速的 app.use() 在表单中使用 enctype="multipart/form-data" 。

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