我有一个问题。我正在使用node.js,我想做一个api调用,这取决于另一个api响应。我不知道。我试图做一些事情,但我遇到了一些错误:
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:356:11)
at ServerResponse.header (C:\workstation\node_modules\express\lib\respons
e.js:719:10)
at ServerResponse.send (C:\workstation\node_modules\express\lib\response.
js:164:12)
at ServerResponse.json (C:\workstation\node_modules\express\lib\response.
js:250:15)
at IncomingMessage.<anonymous> (C:\workstation\server\controllers\apicontroller.js:81:25)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
明确地说,这就是我想要做的: 1 - 调用api以检索包含经度和纬度坐标的响应 2 - 然后通过使用google api对它们进行地理编码,将它们翻译成可读的地址。 3 - 最后在前端显示可读地址。
这是我的代码:
var https = require('https');
var Client = require('node-rest-client').Client;
var client = new Client();
module.exports.getaddresses = function(request,response){
var optionsget = {
host : 'externalhost',
port : 443,
path : '/rest/of/the/api',
method: 'GET',
auth: 'login:pwd'
};
var reqGet = https.request(optionsget, function(res){
var myData = '';
res.on('data', function(d){
myData += d;
});
res.on('end', function(){
var str = JSON.parse(myData);
var locations = [];
var lat, lon, address;
for (var i=0;i<=str.reports.length-1;i++){
lat = str.reports[i].latitude;
lon = str.reports[i].longitude;
var args = {
data: { lat: lat,lon: lon},
headers: { "Content-Type": "application/json" }
};
client.post("http://localhost:3100/api/geocode", args, function (data, myresponse) {
locations.push({
long:str.reports[i].longitude,
latitude:str.reports[i].latitude,
timestamp:str.reports[i].locationts,
address:address
})
});
response.json(locations);
}})
});
reqGet.end();
reqGet.on('error', function(e){
console.error("error:",e);
});
}
有人能帮助我吗?
答案 0 :(得分:1)
您会看到此错误,因为您要在for循环内发回响应,这意味着它会多次执行。每个请求处理程序只应返回一次响应。
您可以通过聚合位置并最终发回一次响应来解决此问题。
var https = require('https');
var Client = require('node-rest-client').Client;
var client = new Client();
module.exports.getaddresses = function (request, response) {
var optionsget = {
host: 'externalhost',
port: 443,
path: '/rest/of/the/api',
method: 'GET',
auth: 'login:pwd'
};
var reqGet = https.request(optionsget, function (res) {
var myData = '';
res.on('data', function (d) {
myData += d;
});
res.on('end', function () {
var str = JSON.parse(myData);
var locations = [];
var lat, lon, address;
for (var i = 0; i <= str.reports.length - 1; i++) {
lat = str.reports[i].latitude;
lon = str.reports[i].longitude;
var args = {
data: { lat: lat, lon: lon },
headers: { "Content-Type": "application/json" }
};
client.post("http://localhost:3100/api/geocode", args, function (data, myresponse) {
locations.push({
long: str.reports[i].longitude,
latitude: str.reports[i].latitude,
timestamp: str.reports[i].locationts,
address: address
})
});
}
})
});
reqGet.end();
reqGet.on('error', function (e) {
console.error("error:", e);
});
response.json(locations);
}
请注意,唯一的变化是将行response.json(locations)
移到for循环之外。
答案 1 :(得分:0)
我注意到在这个URL中,你也在调用项目中的端点。为什么不直接调用函数?
client.post("http://localhost:3100/api/geocode", args, function (data, myresponse) {
locations.push({
long:str.reports[i].longitude,
latitude:str.reports[i].latitude,
timestamp:str.reports[i].locationts,
address:address
})
相反,做这样的事情,
res.on('end', function () {
var str = JSON.parse(myData);
var locations = [];
var lat, lon, address;
for (var i = 0; i <= str.reports.length - 1; i++) {
lat = str.reports[i].latitude;
lon = str.reports[i].longitude;
var args = {
data: { lat: lat, lon: lon },
headers: { "Content-Type": "application/json" }
};
somePostGeoCodeFunction(*Your params to pass*);
});
}
})