我可以在 express 的同一个 api 端点中同时使用 res.json 和 res.sendFile 吗?

问题描述

我想将一个 excel 文件内容上传到服务器以获取其数据并执行一些操作... 我想出了以下代码,但它似乎无法正常工作,因为控制台中显示以下错误 Error: Can't set headers after they are sent.

文件正在上传文件夹中,并且正在显示 json 消息...但是我不知道我将来是否会遇到任何问题...

实际上我只需要excel数据不需要上传excel...也许你可以给我一个解决方法,伙计...

const router = express.Router();

const storage = multer.diskStorage({
  destination(req,file,cb) {
    cb(null,'uploads/');
  },filename(req,cb) {
    cb(
      null,`${file.fieldname}-${Date.Now()}${path
        .extname(file.originalname)
        .toLowerCase()}`
    );
  },});

const excelFilter = (req,cb) => {
  if (
    file.mimetype.includes('excel') ||
    file.mimetype.includes('spreadsheetml')
  ) {
    cb(null,true);
  } else {
    cb('Please upload only excel file.',false);
  }
};
const upload = multer({
  storage,fileFilter: excelFilter,});

router.post('/',upload.single('file'),(req,res) => {
  var workbook = XLSX.readFile(req.file.path);
  var sheet_name_list = workbook.SheetNames;
  var xlData = XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]]);
  res.json(xlData).sendFile(`/${req.file.path}`,{ root: path.resolve() });
});

解决方法

我可以在 express 的同一个 api 端点中同时使用 res.json 和 res.sendFile 吗?

不,你不能。这些方法中的每一种都会发送一个完整的 http 响应(包括调用 res.end() 来终止 http 请求),并且您只能向每个传入请求发送一个 http 响应。您遇到的特定错误与 res.sendFile() 尝试配置它准备发送的响应有关,并发现 http 响应对象已用于发送响应并且无法再次使用.

通常,如果您想发送两段不同的数据,只需将它们组合成一个 Javascript 对象,然后在包含两段数据的对象上调用 res.json()

但是,发送二进制文件不是您可以轻松放入 JSON 包的内容。您可以构建一个多部分响应,其中一部分是 JSON,一部分是文件。您可以对二进制数据进行 JSON 编码(尽管效率低下)。我想可能有一些模块可以帮助您做到这一点,但对于大多数客户来说,这并不是他们真正期望或准备处理的。

找到正确解决方案的唯一方法是让我们了解您在此处尝试实施的客户端/服务器工作流程以及您尝试发回刚刚上传的同一文件的原因。通常没有理由这样做,因为客户端已经拥有这些数据(他们刚刚上传了它)。