使用Node.js "request"模块进行响应编码



我正在尝试从Bing搜索API获取数据,由于现有的库似乎是基于旧的已停产API,我想我会尝试使用request库,这似乎是最常见的库。我的代码看起来像

var SKEY           =  "myKey...." , 
    ServiceRootURL =  'https://api.datamarket.azure.com/Bing/Search/v1/Composite';
function getBingData(query, top, skip, cb) {
    var params = {
         Sources: "'web'", 
         Query: "'"+query+"'", 
         '$format': "JSON", 
         '$top': top, '$skip': skip
       },
       req = request.get(ServiceRootURL).auth(SKEY, SKEY, false).qs(params);
    request(req, cb)
}
getBingData("bookline.hu", 50, 0, someCallbackWhichParsesTheBody)

Bing返回一些JSON,我有时可以使用它,但如果响应主体包含大量非ASCII字符,JSON.parse会抱怨字符串格式错误。我尝试切换到ATOM内容类型,但没有区别,xml无效。检查request()回调中可用的响应体实际上显示了错误的代码。

所以我用一些python代码尝试了同样的请求,看起来一直都很好。供参考:

r = requests.get(
       'https://api.datamarket.azure.com/Bing/Search/v1/Composite?Sources=%27web%27&Query=%27sexy%20cosplay%20girls%27&$format=json', 
        auth=HTTPBasicAuth(SKEY,SKEY))
stuffWithResponse(r.json())

我无法用较小的响应(例如,限制结果的数量)重现问题,也无法识别导致问题的单个结果(通过增加偏移)。我的印象是,响应会被分块读取,以某种方式进行代码转换,然后以一种糟糕的方式重新组装,这意味着如果一些多字节字符被拆分,json/atom数据就会变得无效,这种情况发生在较大的响应上,而不是较小的响应上。

作为节点的新手,我不确定是否有什么应该做的(在某个地方设置编码?Bing返回UTF-8,所以这似乎不需要)。

有人知道发生了什么事吗?

FWIW,我在OSX 10.8上,节点是通过macports安装的v0.8.20,请求是通过npm安装的v2.14.0。

我不确定请求库,但默认的nodejs库对我来说很好。它似乎也比你的库更容易阅读,而且确实是分块返回的。

http://nodejs.org/api/http.html#http_http_request_options_callback或https(如您的req)http://nodejs.org/api/https.html#https_https_request_options_callback(实际上也是一样)

对于选项,一个小提示:使用url解析

var url = require('url');
var params = '{}'
var dataURL = url.parse(ServiceRootURL);
var post_options = {  
    hostname: dataURL.hostname,
    port: dataURL.port || 80,
    path: dataURL.path,
    method: 'GET',  
    headers: {  
        'Content-Type': 'application/json; charset=utf-8',  
        'Content-Length': params.length  
    }  
};

显然params需要是您想要发送的数据

我认为您的请求身份验证不正确。必须在request.get之前提供身份验证。请参阅有关请求HTTP身份验证的文档。qs是一个必须传递给请求选项(如url和auth)的对象。此外,您正在使用相同的req进行第二次请求。您应该知道request.get为给定url的get返回一个流。您使用req的下一个请求将出错。

如果您只需要HTTPBasicAuth,这也应该适用于

//remove req = request.get and subsequent request
request.get('http://some.server.com/', {
  'auth': {
    'user': 'username',
    'pass': 'password',
    'sendImmediately': false
  }
 },function (error, response, body) {
});

回调参数得到3个参数。第一个是适用的错误(通常来自http.Client选项,而不是http.ClientRequest对象)。第二个是http。ClientResponse对象。第三个是响应主体String或Buffer。第二个对象是响应流。若要使用它,必须使用事件"data"、"end"、"error"one_answers"close"。

请确保正确使用参数。

您必须传递选项{json:true}才能对响应进行json解析

最新更新