简体   繁体   English

Express / Node.js中的HTTP请求

[英]HTTP request from within Express/Node.js

I'm trying to set up an express service for a program that I'm writing that contacts an external API and then returns the results so it can be stored in a Mongo I have set up. 我正在尝试为正在编写的程序建立快速服务,该程序与外部API联系,然后返回结果,以便可以将其存储在已设置的Mongo中。

This seems like it should be fairly straightforward, but I'm new to Node.js/Express and I'm getting a "Can't set headers after they are sent" error. 这似乎应该很简单,但是我是Node.js / Express的新手,并且收到“无法在发送标头后设置标头”错误。

I'm getting the data that I want from the external API, but how to send that data properly back to my Angular app.js so it can update in my table? 我从外部API获取所需的数据,但是如何将这些数据正确发送回Angular app.js,以便可以在表中更新?

"addSelected()" is the function I'm calling in my app.js to kick off the process. “ addSelected()”是我在app.js中调用以启动该过程的函数。 The "data" prints part of the way through the full response but then cuts off and gives me the "Can't set Headers after they are sent" error. “数据”会在整个响应过程中进行部分打印,但会中断并显示“发送后无法设置标题”错误。 From what I understand this is from sending the response and then trying to modify the response header after the fact.. but I'm unsure of a workaround or if I'm just formatting everything wrong as this is my first swing at MEAN stack in general. 据我了解,这是从发送响应,然后在事实发生后尝试修改响应标头开始的。.但是我不确定是否有解决方法,或者我是否格式化所有错误,因为这是我在MEAN堆栈中的第一次尝试一般。

I know the problem is on the line "res.send(data)" in server.js but I don't know how to correctly format the response. 我知道问题出在server.js中的“ res.send(data)”行上,但我不知道如何正确格式化响应。

My code: 我的代码:

server.js server.js

//server.js


//setup ==============================
var express = require ('express');
var request = require('request');
var app = express();
var mongoose = require('mongoose');
var https = require('https');

//config ============================
app.use(express.static(__dirname + '/public/'));

console.log("running PipeHelper");

mongoose.connect('mongoedit');
var Schema = mongoose.Schema;
var opSchema = new Schema({

        title: String,
        description: String,
        company: String,
        post_date: String,
        close_date: String,
        contact: String,
        location: String,
        url: String,
        notice_type: String
    });

var item = mongoose.model('item', opSchema);



//routes===========================

//returns full database
app.get('/api/db', function(req, res){

    item.find({},function(err, items){

        if (err) res.send(err);
        res.json(items);
    });

});


//searches FBO for opportunities to add to database
app.get('/api/search:FBO_key', function(req, res){


    var data;
    console.log("2");
    var baseURL = "api.data.gov"
    var params = "/gsa/fbopen/v0/opps?q=" + req.params.FBO_key;
    params += "&api_key="+"keyyyy";
    params += "&all";
    params += "&start=0";
    params += "&p=1";
    params += "&limit=10";
    url = baseURL+params;

    var options = {
        port: 443,
        host: 'api.data.gov',
        path: params,
        method: 'GET'


    };

    //get FBO data
    var request = https.request(options, function(response){
        console.log("4");
        response.on('data', function (chunk){

            //response data to send back to app.js
            data += chunk.toString();
            res.send(data);


        });


    });

    console.log("3");
    request.end();


    request.on('error', function(e){
        console.error(e);
    });


});

app.get('/', function(req,res){

    res.sendfile('./public/index.html');

});

app.listen(8000);

app.js app.js

var app = angular.module("pipeHelper", ['smart-table']);

app.controller('mainCtrl', [
'$scope', '$http', function($scope, $http){

$scope.selected = [];
$scope.displayData= [];
$scope.items=[];
$scope.FBOsearch;



//populates table on startup with whole DB
$http.get('./api/db')
    .success(function(data){
        $scope.items=data;
        $scope.displayData = [].concat($scope.items);

    })
    .error(function(data){
        console.log('Error: '+data);
    });



$scope.addSelected = function(){

    //search FBO, add opportunities, update table
    console.log("1");


    $http.get('./api/search'+'NGA')
    .success(function(data){
        console.log("5");
        console.log(data);
        $scope.items=data;
        $scope.displayData= [].concat($scope.items);

    })
    .error(function(data){

        console.log('Error: ' +data);

    });

};




$scope.isSelected = function(item){
    //if its selected, remove it
    // if its unselected, add it
    if ($scope.selected.indexOf(item)==-1){
        $scope.selected.push(item);
    }
    else{

        $scope.selected.splice($scope.selected.indexOf(item), 1);
    }



    console.log($scope.selected);
    //temp placeholder function.  Eventually add to array of selected objects for placement in Pipeliner/deletion

};







}]);

solved the issue. 解决了这个问题。 I was unaware that response.on('data') gets called multiple times, thus calling my res.send(data) multiple times and incompletely causing it to crash with the error. 我没有意识到response.on('data')被多次调用,因此多次调用了res.send(data)并导致错误导致崩溃。 I added the following to the request function: 我在请求函数中添加了以下内容:

response.on('end'function(){
    res.send(data);
};

basically when the external API data is finished coming in, send it with express. 基本上在外部API数据输入完毕后,用express进行发送。 Learn by doing I suppose. 我想通过做中学。 Hope this helps someone eventually. 希望这最终能对某人有所帮助。

I can't leave a comment, so I will just make it an answer. 我不能发表评论,所以我将其作为答案。

I would recommend installing node-inspector , npm install -g node-debug . 我建议安装node-inspectornpm install -g node-debug Then run your app with node-debug server.js . 然后使用node-debug server.js运行您的应用程序。 This will spawn a new instance of Firefox or Chrome dev tools and allows you to debug your nodeJS code. 这将产生Firefox或Chrome开发工具的新实例,并允许您调试nodeJS代码。 Very useful. 很有用。

The error you are seeing is most likely related to request.end() , if I were to guess. 如果我猜的话,您看到的错误很可能与request.end()有关。 After .end() is called, you can no longer modify the header content. 调用.end()之后,您将无法再修改标头内容。 I doubt it would make a difference, but try putting the request.end() after you have the request.on('error') call. 我怀疑这会有所不同,但是请在调用request.on('error')之后尝试放入request.end()

EDIT: 10/15/15 编辑:10/15/15

I would highly recommend installing VS Code . 我强烈建议安装VS Code It has a built-in debugger for node apps. 它具有用于节点应用程序的内置调试器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM