使用查询字符串参数的node.js http 'get'请求

93

我有一个Node.js应用程序,它是一个HTTP客户端(目前是这样)。所以我正在执行:

var query = require('querystring').stringify(propertiesObject);
http.get(url + query, function(res) {
   console.log("Got response: " + res.statusCode);
}).on('error', function(e) {
    console.log("Got error: " + e.message);
});

这似乎是实现此目的的足够好的方法。 但我有些恼火,因为我不得不执行url + query步骤。 这应该由一个常见库封装,但我还没有在node的http库中看到它存在,也不确定哪个标准npm包可以完成它。 是否有一种更为广泛使用的更好的方法? url.format方法可以节省构建自己的URL的工作。 但理想情况下,请求也应该更高级别。

http://nodejs.org/api/url.html#url_url_format_urlobj - SLaks
https://nodejs.org/api/querystring.html - velop
5个回答

171

看看请求模块。

它比Node.js内置的HTTP客户端更加功能齐全。

var request = require('request');

var propertiesObject = { field1:'test1', field2:'test2' };

request({url:url, qs:propertiesObject}, function(err, response, body) {
  if(err) { console.log(err); return; }
  console.log("Get response: " + response.statusCode);
});

一个典型的propertiesObject会是什么样子?我无法让它工作。 - user264230
3
qs是查询字符串键。因此,您想在查询字符串中包含哪些字段就使用什么字段,例如{field1:'test1',field2:'test2'}。 - Daniel
有人知道如何只使用Nodejs核心http模块来完成这个吗? - Alexander Mills
1
@AlexanderMills 请看我的回答。不需要第三方库。 - Justin Meiners
20
请求模块现已过时且已被弃用。 - AmiNadimi

35

无需第三方库。使用nodejs url 模块构建带有查询参数的URL:

const requestUrl = url.parse(url.format({
    protocol: 'https',
    hostname: 'yoursite.com',
    pathname: '/the/path',
    query: {
        key: value
    }
}));

然后使用格式化的URL发出请求。 requestUrl.path 将包括查询参数。

const req = https.get({
    hostname: requestUrl.hostname,
    path: requestUrl.path,
}, (res) => {
   // ...
})

1
我将尝试使用这个解决方案,因为我想使用一些现有的代码,该代码使用内置的 https。然而,OP要求更高级别的抽象和/或库来组合带查询的URL字符串,因此我认为被接受的答案在个人上更有效。 - Scott Anderson
9
@ScottAnderson,如果我不是被采纳的答案也没关系。我只想帮助人们完成他们需要做的事情。很高兴它能够帮到你。 - Justin Meiners

8

如果您不想使用外部包,只需在您的工具中添加以下函数:

var params=function(req){
  let q=req.url.split('?'),result={};
  if(q.length>=2){
      q[1].split('&').forEach((item)=>{
           try {
             result[item.split('=')[0]]=item.split('=')[1];
           } catch (e) {
             result[item.split('=')[0]]='';
           }
      })
  }
  return result;
}

然后,在 createServer 的回调函数中,向 request 对象添加属性 params
 http.createServer(function(req,res){
     req.params=params(req); // call the function above ;
      /**
       * http://mysite/add?name=Ahmed
       */
     console.log(req.params.name) ; // display : "Ahmed"

})

2
OP的问题涉及HTTP客户端,而不是HTTP服务器。这个答案适用于解析HTTP服务器中的查询字符串,而不是为HTTP请求编码查询字符串。 - Stephen Schaub
这个做法与问题要求的相反,而且最好使用Node内置的querystring模块,而不是尝试自己解析。 - peterflynn

6
我一直在苦恼如何向我的URL添加查询字符串参数。 直到意识到需要在我的URL末尾添加?,否则它将无法正常工作。 这非常重要,因为它可以节省您数小时的调试时间,相信我:我已经经历过了。
下面是一个简单的API端点,调用Open Weather API并将APPIDlatlon作为查询参数传递,并返回天气数据作为JSON对象。 希望这可以帮助到您。
//Load the request module
var request = require('request');

//Load the query String module
var querystring = require('querystring');

// Load OpenWeather Credentials
var OpenWeatherAppId = require('../config/third-party').openWeather;

router.post('/getCurrentWeather', function (req, res) {
    var urlOpenWeatherCurrent = 'http://api.openweathermap.org/data/2.5/weather?'
    var queryObject = {
        APPID: OpenWeatherAppId.appId,
        lat: req.body.lat,
        lon: req.body.lon
    }
    console.log(queryObject)
    request({
        url:urlOpenWeatherCurrent,
        qs: queryObject
    }, function (error, response, body) {
        if (error) {
            console.log('error:', error); // Print the error if one occurred

        } else if(response && body) {
            console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
            res.json({'body': body}); // Print JSON response.
        }
    })
})  

如果您想使用 querystring 模块,请进行以下更改。
var queryObject = querystring.stringify({
    APPID: OpenWeatherAppId.appId,
    lat: req.body.lat,
    lon: req.body.lon
});

request({
   url:urlOpenWeatherCurrent + queryObject
}, function (error, response, body) {...})

2
如果你需要向一个IP地址和域名发送GET请求(其他答案没有提到你可以指定一个端口变量),可以使用这个函数:
function getCode(host, port, path, queryString) {
    console.log("(" + host + ":" + port + path + ")" + "Running httpHelper.getCode()")

    // Construct url and query string
    const requestUrl = url.parse(url.format({
        protocol: 'http',
        hostname: host,
        pathname: path,
        port: port,
        query: queryString
    }));

    console.log("(" + host + path + ")" + "Sending GET request")
    // Send request
    console.log(url.format(requestUrl))
    http.get(url.format(requestUrl), (resp) => {
        let data = '';

        // A chunk of data has been received.
        resp.on('data', (chunk) => {
            console.log("GET chunk: " + chunk);
            data += chunk;
        });

        // The whole response has been received. Print out the result.
        resp.on('end', () => {
            console.log("GET end of response: " + data);
        });

    }).on("error", (err) => {
        console.log("GET Error: " + err);
    });
}

请勿忘记在文件顶部引入所需的模块:
http = require("http");
url = require('url')

同样要记住,您可以使用 https 模块进行安全网络通信。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接