【问题标题】:node-rest-client: Can't set headers after they are sent.node-rest-client:发送后无法设置标头。
【发布时间】:2017-10-21 22:08:15
【问题描述】:

我正在尝试使用 node-rest-client 从节点调用 REST API。如果我的调用返回错误,我想捕获错误并将其报告给调用者。

我正在用 Postman 尝试这个,不幸的是这只能工作一次。当我第二次按发送时,我的 node.js 程序崩溃并出现错误“发送后无法设置标题。”

我是 node.js 的新手,非常感谢任何帮助!

//app stuff
const client_id = "x";
const client_secret = "y";
const callback = "https://myurl;

// Basic Setup
var http     = require('http'),
    express  = require('express'),
    mysql    = require('mysql'),
    parser   = require('body-parser'),
    Client   = require('node-rest-client').Client;

var client = new Client();

// Setup express
var app = express();
app.use(parser.json());
app.use(parser.urlencoded({ extended: true }));
app.set('port', process.env.PORT || 5000);

// Set default route
app.get('/', function (req, res) {
    res.send('<html><body><p>Welcome to Bank API Wrapper</p></body></html>');
});

app.post('/authorize', function (req,res) {
    var response = [];

    if (typeof req.body.code !== 'undefined' && typeof req.body.state !== 'undefined' ){
        var code = req.body.code, state = req.body.state;

        //conversion to base64 because citi api wants it this way
        var authorization = "Basic " + Buffer.from(client_id + ":" + client_secret).toString('base64');

        var args = {
            data:{"grant_type":"authorization_code","code":code,"redirect_uri":callback},
            headers:{"Authorization":authorization,"Content-Type":"application/x-www-form-urlencoded"} 
        };

        //get access and refresh token
        client.post("https://sandbox.apihub.citi.com/gcb/api/authCode/oauth2/token/sg/gcb", args, function (citidata, citiresponse) {
            //console.log(citidata);
            //console.log(citiresponse);
        });

        client.on('error', function (err) {
            response.push({'result' : 'error', 'msg' : 'unauthorized access'});
            res.setHeader('Content-Type', 'application/json');
            res.status(200).send(JSON.stringify(response));
        });
    } 
    else {
        response.push({'result' : 'error', 'msg' : 'Please fill required details'});
        res.setHeader('Content-Type', 'application/json');
        res.status(200).send(JSON.stringify(response));
    }
});


// Create server
http.createServer(app).listen(app.get('port'), function(){
    console.log('Server listening on port ' + app.get('port'));
});

【问题讨论】:

  • 程序的“请填写必填项”部分没有问题。问题出在 client.on('error' 部分。它只工作一次。之后,我收到错误“发送后无法设置标头。”

标签: node.js node-rest-client


【解决方案1】:

你有这个:

client.on('error', function (err) {

这会在client 上注册一个错误处理程序,但它永远不会被删除。 client 在请求之间共享,因此后续请求中的任何错误仍会触发旧的错误处理程序。

相反,您可以侦听请求中的错误。像这样的:

var request = client.post("...

request.on('error', function(err) {
    // handle error
});

https://www.npmjs.com/package/node-rest-client#error-handling

【讨论】:

  • 试了一下,得到了这个。只有 client.on('error.").. 捕获错误。 events.js:165 throw err; ^ Error: Uncaught, unspecified "error" event. (Error parsing response.response: [{"type":"bad请求","代码":"400"....
  • 我通过移动 var client = new Client(); 解决了这个问题在 app.post 中。谢谢!您在请求之间共享客户端的评论非常有用!谢谢!
  • @JacksonNg 我自己测试了它并使用我描述的请求错误处理程序确实捕获了错误。没有必要将 Client 创建移动到 app.post 中。
  • 有趣的是它对我不起作用。似乎 client.on 捕获了错误,但 request.on 没有。
猜你喜欢
  • 2017-08-11
  • 1970-01-01
  • 2018-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-18
  • 1970-01-01
相关资源
最近更新 更多