【问题标题】:node.js http 'get' request with query string parameters带有查询字符串参数的node.js http'get'请求
【发布时间】:2013-05-30 00:02:15
【问题描述】:

我有一个 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 的工作。但理想情况下,请求也会比这更高。

【问题讨论】:

标签: node.js http query-string


【解决方案1】:

查看request 模块。

比node内置的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 看起来如何?我不能让它工作
  • qs 是查询字符串键。那么你想要在查询字符串中的任何字段。 {field1:'test1',field2:'test2'}
  • 有人知道如何仅使用 Nodejs 核心 http 模块来做到这一点吗?
  • @AlexanderMills 看到我的回答。不需要第三方库。
  • 请求模块现已过时并已弃用。
【解决方案2】:

如果您不想使用外部包,只需在实用程序中添加以下功能:

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回调中,将属性params添加到request对象:

 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"

})

【讨论】:

  • OP 的问题涉及 http 客户端,而不是 http 服务器。这个答案与在 http 服务器中解析查询字符串有关,而不是为 http 请求编码查询字符串。
  • 这与问题所问的相反,而且最好使用Node's built-in querystring module 而不是自己尝试解析。
【解决方案3】:

我一直在努力解决如何将查询字符串参数添加到我的 URL。直到我意识到我需要在我的 URL 末尾添加 ? 之前,我才能让它工作,否则它将无法工作。这一点非常重要,因为它可以为您节省数小时的调试时间,相信我:去过那里......完成了。

下面是一个简单的 API 端点,它调用 Open Weather API 并将 APPID、lat 和 lon 作为查询参数传递,并将天气数据作为 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) {...})

【讨论】:

    【解决方案4】:

    不需要第 3 方库。使用 nodejs url module 构建带有查询参数的 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) => {
       // ...
    })
    

    【讨论】:

    • 我将尝试使用这个解决方案,因为我想使用一些使用内置 https 的现有代码,但是 OP 要求更高级别的抽象和/或库用查询组合 URL 字符串,所以我认为接受的答案个人更有效
    • @ScottAnderson 如果我不是公认的答案,我很好。只是想帮助人们完成他们需要做的事情。很高兴它可以帮助你。
    【解决方案5】:

    如果您需要向IP 和Domain 发送GET 请求(其他答案未提及您可以指定port 变量),您可以使用此功能:

    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 模块通过安全网络进行通信。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      • 1970-01-01
      • 2021-10-04
      • 2012-02-07
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多