【问题标题】:Why can't I send the response status inside a spawn answer?为什么我不能在生成答案中发送响应状态?
【发布时间】:2021-07-04 21:03:09
【问题描述】:

在我的节点 Api 中,我对特定端点使用以下函数来创建 PDF 并返回其名称:

exports.findOne = (req, res) => {
  .
  .
  .
 const { spawn } = require('child_process');
 const ls = spawn('pdflatex', [name], {cwd: '/path'});

 ls.stdout.on('data', (data) => {
   console.log(`stdout: ${data}`);});

 ls.stderr.on('data', (data) => {
   console.error(`stderr: ${data}`);
 });

 res.status(200).send({ message: name.split('.tex')[0] });
};

这很好用,但在创建 PDF 之前会返回 PDF 的名称。所以我更改了函数,以便仅在创建 pdf 后返回名称:

exports.findOne = (req, res) => {
  .
  .
  .
 const { spawn } = require('child_process');
 const ls = spawn('pdflatex', [name], {cwd: '/path'});

 ls.stdout.on('data', (data) => {
   console.log(`stdout: ${data}`);});
   res.status(200).send({ message: name.split('.tex')[0] });

 ls.stderr.on('data', (data) => {
   console.error(`stderr: ${data}`);
   res.status(401).send({ message: "PDF Err" });
 });
};

我得到错误:

stdout: This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/Debian) (preloaded format=pdflatex)
restricted \write18 enabled.

_http_outgoing.js:491
throw new Error('Can\'t set headers after they are sent.');
^

Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:491:11)
at ServerResponse.setHeader (_http_outgoing.js:498:3)
at ServerResponse.header (/.../response.js:771:10)
at ServerResponse.send (/.../response.js:170:12)
at ServerResponse.json (/.../response.js:267:15)
at ServerResponse.send (/.../response.js:158:21)
at Socket.ls.stdout.on (/....report.controller.js:60:18)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at Socket.Readable.push (_stream_readable.js:208:10)
at Pipe.onread (net.js:607:20)

您有什么想法可以解决这个问题,并且只有在创建 pdf 后才能发送答案?谢谢!

【问题讨论】:

    标签: node.js stdout http-status-codes spawn pdflatex


    【解决方案1】:

    要在生成 PDF 文件后发送响应,您可以使用 stdout 中的事件 close。 当spawn 命令完成时会触发。

    ls.stdout.on('close', () => {...});

    【讨论】:

      【解决方案2】:

      您可以获得多个 data 事件,这会导致您尝试多次发送响应,从而导致您看到的错误。

      如果您想等到生成的进程完成,那么您应该监听close 事件并在其中发送您的响应。

      exports.findOne = (req, res) => {
        .
        .
        .
       const { spawn } = require('child_process');
       const ls = spawn('pdflatex', [name], {cwd: '/path'});
      
       ls.stdout.on('data', (data) => {
         console.log(`stdout: ${data}`);});
      
       ls.stderr.on('data', (data) => {
         console.error(`stderr: ${data}`);
       });
      
       ls.on('close', (code) => {
         if (!code) {
             res.send({ message: name.split('.tex')[0] });
         } else {
             console.log('error code: ', code);
             res.status(401).send({ message: "PDF Err" });
         }
       }).on('error', (err) => {
          console.log(err);
          res.sendStatus(500);
       });
      
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-07
        • 1970-01-01
        • 2017-12-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多