4

我是 nodeJS 和异步编程的新手。我使用 express 作为我的应用程序的基础,实际上只有一个路由提供页面并接受来自表单的上传。上传文件后,我想向外部服务发出 POST 请求。尝试在 res.send(200) 之后执行任何代码但是会导致错误消息Error: Can't set headers after they are sent.

我正在使用请求包将帖子发布到外部服务。

var express = require('express');
var router = express.Router();
var util = require("util");
var request = require("request");

/* POST uploads. */
router.post('/', function(req, res, next) {
    console.log("LOG:" + util.inspect(req.files));
    res.send('respond with a resource');
    postFile(req.files.file.path);
});

var postFile = function(path) {
    var opts = {
        method: 'POST',
        uri: 'https://example.com/api/files.upload',
        formData: {
            token: "xxx",
            file: fs.createReadStream(req.files.file.path)
        }
    }

    // console.log("LOG:\n" + util.inspect(opts));

    request.post(opts, function(error, response, body) {
        if (error) {
            console.log("ERROR LOG: " + util.inspect(error));
        } else {
            console.log("RESPONSE LOG:" + util.inspect(response));
        }
    });
}

module.exports = router;

postFile 函数本身可以正常工作,甚至在 res.send 之后直接添加 console.log 也会导致相同的错误。响应发送到客户端后,如何继续在服务器上执行代码?

从节点输出日志:

POST /uploads 200 85.201 ms - 23 Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11) at ServerResponse.header (/Users/jason/dev/test/file-share/node_modules/express/lib/response.js:700:10) at ServerResponse.send (/Users/jason/dev/test/file-share/node_modules/express/lib/response.js:154:12) at fn (/Users/jason/dev/test/file-share/node_modules/express/lib/response.js:934:10) at View.exports.renderFile [as engine] (/Users/jason/dev/test/file-share/node_modules/jade/lib/index.js:374:12) at View.render (/Users/jason/dev/test/file-share/node_modules/express/lib/view.js:93:8) at EventEmitter.app.render (/Users/jason/dev/test/file-share/node_modules/express/lib/application.js:566:10) at ServerResponse.res.render (/Users/jason/dev/test/file-share/node_modules/express/lib/response.js:938:7) at /Users/jason/dev/test/file-share/app.js:58:7 at Layer.handle_error (/Users/jason/dev/test/file-share/node_modules/express/lib/router/layer.js:58:5)

4

2 回答 2

2

下面的代码没有错,响应请求后即可执行代码。您只是不能再次发送标头。

router.post('/', function(req, res, next) {
  console.log("LOG:" + util.inspect(req.files));
  res.send('respond with a resource');
  postFile(req.files.file.path);
});

除非您愿意,否则使用POST 或 GET请求将不会响应您的请求。

于 2015-03-05T02:33:35.953 回答
0

您的postFile()函数req.files.file.path在这一行中指的是:

file: fs.createReadStream(req.files.file.path)

req对象没有被传递给它。这应该会产生某种异常。

看来您应该只使用:

file: fs.createReadStream(path)

因为您正在传递postFile(path).

于 2015-03-05T03:38:20.223 回答