我对我一直在做的小项目有疑问。它本质上是一种允许以更加安静的方式在WFS服务器上进行查询的服务。我的问题是我收到的响应是完全的胡言乱语,但只有当我在Red Hat OpenShift或Heroku上部署我的项目时。在Cloud9上,一切都很完美。请注意,我一直在使用此项目作为教自己express和nodejs的方法,并且编码可能不是最佳的。
我的主要问题是WFS服务器在ISO-8859-1中返回带有法语重音字符的数据,在处理响应时我丢失了它们,它们会变成乱码或�字符。
我尝试了两种不同的方法来解决这个问题,在部署时都会返回乱码。对于第一个使用collect
方法扩展请求,以替换error
,data
和end
事件。基本上我查询WFS,如果传递了format
参数,我使用xml2js
节点模块转换json中的响应。
req.pipe(request.get(app.get('baseUrl') + '&REQUEST=getcapabilities')).collect(function(err, body) {
if(err)
return next(err);
if(req.query.format && req.query.format.toLowerCase() == 'json'){
parseString(body,{mergeAttrs: true}, function(err, result){
if(err)
return next(err);
res.json(200, result);
});
}else if(!req.query.format){
res.type('application/xml; charset=utf-8');
res.send(200, body);
}else{
next(new Error('Le paramètre \'format\' n\'est pas du valide. La valeur acceptée est JSON.'));
}
});
这里是collect
,我从iconv-lite
模块中得到了这个想法。
request.Request.prototype.collect = function(cb){
var res = [];
this.on('error', cb);
this.on('data', function(chunk){ res.push(chunk); });
this.on('end', function(){
cb(null, Buffer.concat(res).toString('binary'));
});
return this;
};
在Cloud9上它返回数据没有问题,在OpenShift上我得到了这个回复:
¥UMoâ0½ó+¢\zj[ÔE@è¶BâK]íÍ2É4xÛ©=.ð±hKÕîºÍ)¶çͼyãw®62ÁX¡U÷¬5ÏPNʺáp>=¿¼üúí¼W½FÇ&+¼rN¸[ðºá
±hDZäCþ¢LØÈIAêvà SHeÛÒ~¥³ä[¯×.@ ÓYød¹±éËõE¤Mi6[ñ¯ñh^åòdïcÛÎdþ&:«,!
o´×pÏ]ÝðÁñ\ÜHãæa3"u{
t,´Á@½õõ·¯ËH'+5j¿mOñEÔZñ[( ñAMº¢Ð
ÇûÉæÃÅw6ë/îãédرI1Nèg¾¯ÌáÃmA iÛÿÄ-Èò%Öº¥E®LàÖhWtCâÖf7ÀÑ8L´,rØþd¬W;ÀZ!¥Ù«t`C˲A©Ê>t`Íà
báÁQ§@ïY'òI{ZmXkSú=ìÍÕÅàv¯j$ÎÐ=lÒo«V¿b¢%K[
PÄ÷]Ôl¥Q{Ø_-¥;gX
,ç¬ðt2ÓÅ,Ô°"wÖ=LéZ+ü@»L9RÝývF¤jíí;¤`¸ó#
#.«.(Ó´'XAQðÑÍtûDØߺvVpIÇÃÅPsðÃòÌ«ÚYæ<AÍÌ.+ä)µ(ÛÅ£»OâÇNªL~ °Ö'ÐC3õhz<1×`#
ÏjÏ·
W,°iH
á×DöX{ÆßuâÓAÜÓ¼úñë©Ü+§/½,ú±ì5þ¯
Êì
对于第二种方式,在阅读后我尝试使用iconv-lite模块解码UTF-8中的响应。
req.pipe(request.get({encoding: null, url:app.get('baseUrl') + '&REQUEST=DescribeFeatureType' + ((req.params.qTypeName) ? '&TYPENAME='+req.params.qTypeName : '' )}, function(err, response, body) {
if(err)
return next(err);
body = iconv.decode(new Buffer(body), "ISO-8859-1");
if(req.query.format && req.query.format.toLowerCase() == 'json'){
parseString(body,{mergeAttrs: true}, function(err, result){
if(err)
return next(err);
res.json(200, result);
});
}else if(!req.query.format){
res.type('application/xml; charset=utf-8');
res.send(200, body);
}else{
next(new Error('Le paramètre \'format\' n\'est pas du valide. La valeur acceptée est JSON.'));
}
})
);
我仍然得到与我尝试的第一种方式相同的结果。虽然我通常会尝试自己解决问题,但我想我在这里碰壁了。就像我说的那样,我仍在学习nodejs并表达,所以这可能是一个非常简单的事情,我没有考虑到。阅读后我怀疑它与编码有关,但是我的错误是它在Cloud9上工作正常并且只在部署时才会中断。
对于长长的代码和文字感到抱歉,但我希望尽可能清楚,英语不是我的主要语言,所以如果你需要澄清,请随便提出。
谢谢!
答案 0 :(得分:0)
好吧,似乎在花时间写出这个大问题后,我能够找出问题所在。这是我遗忘的旧代码的残余,req.pipe(...)
。在我决定添加选项以返回json之前,我曾经直接将流管道传输到res
。
这种方式效果很好。虽然它没有解释为什么它在Cloud9开发环境中运行良好。在将此标记为答案之前,我会等待一段时间,以便我可以从其他人那里获得见解。
request.get({encoding: null, url:app.get('baseUrl') + '&REQUEST=DescribeFeatureType' + ((req.params.qTypeName) ? '&TYPENAME='+req.params.qTypeName : '' )}, function(err, response, body) {
if(err)
return next(err);
body = iconv.decode(new Buffer(body), "ISO-8859-1");
if(req.query.format && req.query.format.toLowerCase() == 'json'){
parseString(body,{mergeAttrs: true}, function(err, result){
if(err)
return next(err);
res.json(200, result);
});
}else if(!req.query.format){
res.type('application/xml; charset=utf-8');
res.send(200, body);
}else{
next(new Error('Le paramètre \'format\' n\'est pas du valide. La valeur acceptée est JSON.'));
}
});