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

rif*_*aff 7 http request character-encoding bing node.js

我试图从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)
Run Code Online (Sandbox Code Playgroud)

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())
Run Code Online (Sandbox Code Playgroud)

我无法用较小的响应重现问题(例如限制结果的数量)并且无法识别导致问题的单个结果(通过加强偏移).我的印象是,响应以块的形式读取,以某种方式进行转码并以错误的方式重新组装,这意味着如果某些多字节字符被拆分,则json/atom数据将变为无效,这发生在较大的响应但不是较小的响应.

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

任何人都知道发生了什么事吗?

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

rob*_*mes 1

我不确定 request 库,但默认的 Nodejs 库对我来说效果很好。它看起来也比你的库更容易阅读,而且确实会分块返回。

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

对于选项有一点提示:使用 url parse

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  
    }  
};
Run Code Online (Sandbox Code Playgroud)

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