multer 错误未作为响应发送。请求一直待处理

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

我正在创建一个文件上传功能,以将多个文件(图像)上传到 Express 应用程序。我已经配置了 multer 中间件的大小限制和文件 mimetypes,如下所示:

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, 'uploads/product_images/');
    },
    filename: function (req, file, cb) {
        cb(null, "product-" + Date.now() + '-' + uuidv4() + "-" + file.originalname);
    }
});

const upload = multer({
    storage: storage,
    limits: {
        fileSize: 1024 * 1024 * 5
    },
    fileFilter: function (req, file, cb) {
        if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
            cb(null, true);
        } else {
            cb(new Error('Invalid file type, only JPEG and PNG are allowed!'));
        }
    }
}).array("images")

为了处理 multer 中 cb 给出的错误,我创建了一个错误处理程序中间件,将其放置在所有 ProductRoutes 后面,如下所示:

const productRouter = express.Router();

productRouter
    .get('/', fetchProductsList)
    .get('/:product_id/:size', validateProductDB, fetchProductById)
    .post('/', isAuth, upload, validateProduct, handleValidationErrors, createProduct)
    .patch('/:id', upload, updateProduct)
    .delete('/:id', deleteProduct)
    .get('/colors', fetchColors)
    .get('/sizes', fetchSizes)
    .get('/genders', fetchGenders)

// Custom error handler for Multer errors
productRouter.use((err, req, res, next) => {
    if (err instanceof multer.MulterError) {
        // A Multer error occurred when uploading.
        console.log("message from multer instance : ", err.message)
        return res.status(400).json({ errors: [{ msg: err.message }] });
    } else if (err) {
        // An unknown error occurred when uploading.
        console.log("message not from multer instance : ", err.message)
        return res.status(400).json(err.message);
    }
    next();
});

当我尝试上传非图像且大于大小限制的文件时,我没有收到任何响应。但我从自定义错误处理程序中间件在控制台中打印了错误。

另一个事实:邮递员中一切正常。

这段代码有什么问题。 要查看完整代码,请访问此存储库:https://github.com/ishanjarwal/mern-sneaker-store 请解释问题的原因以及可能的解决方案。

express http file-upload backend multer
1个回答
0
投票

你在后台所做的一切已经足够了。 注意的是前端要注意的地方,尤其是fetch返回的promise

  • 如果请求已到达服务器,则承诺将始终得到解决。
  • 如果请求未到达服务器,则 Promise 将始终拒绝,这意味着存在网络错误。 请注意,此类错误还包括 CORS 错误。

您可以看到这个问题已经被多个帖子回答过。请在此处查看实例:https://stackoverflow.com/questions/61113344/fetch-api-how-to-define-if-an-error-is-a-network-error

本文的以下部分显示了服务器和 HTML 客户端的最少代码。此代码的目的是演示三种情况的操作。当您运行前端表单时,您将会对这里提到的三种情况有更多的了解。针对每种情况提供的三个按钮将运行相应的代码并提供有关每个上下文的反馈。 请您查看后端和前端的代码,以便完整地了解此演示。

如果需要澄清,请发表评论。

服务器.js

const express = require('express');
const app = express();

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

app.get('/success', (req, res) => {
  res.status(200).json({ error: null, data: 'some data' });
});

app.get('/failure', (req, res) => {
  res.status(400).json({ error: 'some error text', data: null });
});

app.listen(3000, () => console.log('L@3000'));

index.html

<!DOCTYPE html>
<htm>
  <head>
    Handling HTTP error code 400
  </head>
  <body>
    <br />
    <br />
    <label>Request Not reaching server - Promise will reject always</label>
    <button id="button1">Test and see</button>
    <br />
    <br />
    <label
      >Request Reached server, and then server respons with success code -
      Promise will resolve always</label
    >
    <button id="button2">Test and see</button>
    <br />
    <br />
    <label
      >Request Reached server, and then server respons with failure code -
      Promise will resolve always</label
    >
    <button id="button3">Test and see</button>
    <br />
    <br />
    <p></p>
  </body>
  <script>
    const p = document.querySelector('p');
    const b1 = document.querySelector('#button1');
    const b2 = document.querySelector('#button2');
    const b3 = document.querySelector('#button3');

    b1.onclick = function () {
      fetch('http://localhost:300', {
        method: 'GET',
      })
        .then((data) => (p.textContent = JSON.stringify(data)))
        .catch((error) => (p.textContent = error));
    };

    b2.onclick = function () {
      fetch('http://localhost:3000/success', {
        method: 'GET',
      })
        .then((data) => data.json())
        .then((data) => {
          p.textContent = JSON.stringify(data);
        })
        // catch will not reach since there is no network error
        .catch((error) => (p.textContent = error));
    };

    b3.onclick = function () {
      fetch('http://localhost:3000/failure', {
        method: 'GET',
      })
        .then((response) => {
          if (!response.ok) {
            throw new Error(`Failure Response status ${response.status}`);
          }
          return data.json();
        })
        // then will not reach since there is a failure response
        .then((data) => (p.textContent = JSON.stringify(data)))
        .catch((error) => (p.textContent = error));
    };
  </script>
</htm>
© www.soinside.com 2019 - 2024. All rights reserved.