HTTP响应在Nodejs / Express中完全是乱码

时间:2014-09-11 14:08:17

标签: node.js express openshift

我对我一直在做的小项目有疑问。它本质上是一种允许以更加安静的方式在WFS服务器上进行查询的服务。我的问题是我收到的响应是完全的胡言乱语,但只有当我在Red Hat OpenShift或Heroku上部署我的项目时。在Cloud9上,一切都很完美。请注意,我一直在使用此项目作为教自己express和nodejs的方法,并且编码可能不是最佳的。

我的主要问题是WFS服务器在ISO-8859-1中返回带有法语重音字符的数据,在处理响应时我丢失了它们,它们会变成乱码或�字符。

我尝试了两种不同的方法来解决这个问题,在部署时都会返回乱码。对于第一个使用collect方法扩展请求,以替换errordataend事件。基本上我查询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上工作正常并且只在部署时才会中断。

对于长长的代码和文字感到抱歉,但我希望尽可能清楚,英语不是我的主要语言,所以如果你需要澄清,请随便提出。

谢谢!

1 个答案:

答案 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.'));
    }

});