首页 > 解决方案 > Multer 文件上传在服务器上以 500 退出,但在 localhost 上工作(使用 Postman 测试)

问题描述

我正在使用 multer 作为中间件为 Node.js (Express) 后端实现文件上传,以处理修补的表单数据。在本地主机上运行应用程序时,上传工作非常好(使用 Postman formdata);但是,当使用它时,使用我的服务器 multer 继续返回 500 退出代码。尽管在过去两天进行了各种修改,但我没有设法将任何文件上传到我的服务器文件系统。

由于我对 node.js 和 multer 很陌生,因此非常感谢任何帮助


前端表单数据

        let formData = new FormData();
        formData.append('fileType', 'img');
        formData.append('filePath', 'uploads/img/profile');
        formData.append('profileImg', input.files[0]);

        fetch("https://****", {
            method: 'PATCH',
            headers: {
                'Authorization': `Bearer ${localStorage.getItem('token')}`,
                'Content-Type': 'multipart/form-data'
            },
            body: formData
        })
            .then((res) => console.log(res))
            .catch((err) => ("Error occurred", err));

后端快速服务器设置(只是我认为可能会出现任何问题的摘录)

app.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', 'https://****');
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Allow-Methods', 'GET,HEAD,PUT,PATCH,POST,DELETE');
    res.header('Access-Control-Expose-Headers', 'Content-Length');
    res.header('Access-Control-Allow-Headers', 'Accept, Authorization, Content-Type, X-Requested-With, Range');
    if (req.method === 'OPTIONS') {
        return res.sendStatus(200);
    } else {
        return next();
    }
});

app.use(express.static('uploads'));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true })); //prev set to false
app.use(cookieParser());

AuthorizationRouter.routesConfig(app);
UsersRouter.routesConfig(app);

后端 Multer 设置

const multer = require('multer');
let fileSizeLimit;

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, `./${req.body.filePath}/`)
    },
    filename: function (req, file, cb) {
        const uniqueSuffix = Date.now() + Math.round(Math.random() * 1E9)
        cb(null, `${uniqueSuffix}_${file.originalname}`)
    }
})

const fileFilter = (req, file, cb) => {
    //Handling more cases here - just for illustrative purposes 
    let fileRestriction;
    switch (req.body.fileType) {
        case 'file':
            fileRestriction = ['image/jpeg', 'application/pdf', 'image/jpeg'];
            fileSizeLimit = 100000000; // = 100mb
            break;
    }
    fileRestriction.includes(file.mimetype) === true ? cb(null, true) : cb(null, false);
}

exports.upload = multer({
    storage: storage,
    limits: {
        fileSize: fileSizeLimit
    },
    fileFilter: fileFilter
})

后端 multer 用作中间件

app.patch('/users/:userId', [
    ValidationMiddleware.validJWTNeeded,
    Upload.upload.fields([
        {name: 'profileImg', maxCount: 1}, {name: 'cv', maxCount: 1}, {name: 'voiceMessage', maxCount: 1}, {name: 'brochure', maxCount: 1}, {name: 'video', maxCount: 1}
    ]),
    UsersController.patchById
]);

标签: node.jsexpressfilemulter

解决方案


Content-Type使用 fetch 发送 FormData 时不必指定标头。如果这样做,它会与浏览器为您应用的表单边界混淆,这使得请求在到达服务器时无法解析。

请改为执行以下操作:

fetch("https://****", {
  method: 'PATCH',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('token')}`,
  },
  body: formData
});

推荐阅读