Encoding error using node.js

I am rewriting a small python script in node.js. The original script worked as follows:

# -*- coding: utf-8 -*-
import urllib
import httplib
import json

def rpc(url, args = { }):
  try:
    post_data = json.dumps({'args': args})
    f = urllib.urlopen(url, post_data)
    if not f or f.code != 200:
      return { 'result': 1, 'error': 'urlopen returned error' }
    data = f.read()
    js_data = json.loads(data)
  except Exception, e:
    return { 'result': 2, 'error': e }
  else:
    return { 'result': 0, 'data': js_data }

print rpc('http://server.local/rpc', {'x': u''})

I use request to do the same in node.js:

var request = require('request')

request.post('http://server.local/rpc', {
    json: {'x': ''}
}, function(err, result) {
    console.log(err, result.body)
})

It works, but the data in unicode is distorted, so when I request data, I get ÑеÑÑinstead . It seems strange considering that both python and node.js should send data encoded in utf8.

Btw, the server is written in Perl, I think, but all I know about it: (

In addition, the server returns Unicode data for other requests, therefore can do it.

Upd. my console prints Unicode characters perfectly.

Upd. Rewrote my code to use the node.js module http:

var http = require('http')

var options = {
  hostname : 'server.local',
  path     : '/rpc',
  method   : 'POST'
}    
var req = http.request(options, function (res) {
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
});    
var body = JSON.stringify({'x': ''})    
req.setHeader('Content-length', body.length)    
// python sends data with this header
req.setHeader('Content-type', 'application/x-www-form-urlencoded')

req.on('error', function (e) {
  console.log('problem with request: ' + e);
});    
req.end(body, 'utf8');

, , . ( MBA Debian). , , node.js Unicode.

+3
4

, python script:

POST / HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 43
Host: localhost:1234
User-Agent: Python-urllib/1.17

{"args": {"x": "\u0442\u0435\u0441\u0442"}}

, node.js:

POST /rpc HTTP/1.1
Host: localhost:1234
Content-length: 12
Content-type: application/x-www-form-urlencoded
Connection: keep-alive

{"x":""}

? JSON.stringify - utf8, python ascii.

rpc utf8, json . , :

var request = require('request');
var jju = require('jju');

request.post({
   uri: 'http://localhost:8080/rpc',
   body: jju.stringify({args: {x: ""}}, {
       mode: 'json',
       indent: false,
       ascii: true,
   }),
}, function(err, res, body) {
    console.log(body);
});

:

POST /rpc HTTP/1.1
host: localhost:8080
content-length: 41
Connection: keep-alive

{"args":{"x":"\u0442\u0435\u0441\u0442"}}

, python.

+1

, .

http.request request, , request .

, utf8 .

request, , , , , , , , node http.request , .

0

, , , . , , .

body.length "" . US-ASCII 1 = 1 , , US-ASCII.

, US-ASCII, , Content-length.

http://en.wikipedia.org/wiki/UTF-8

15 :

var utf8overLoad = encodeURIComponent(body).match(/%[89ABab]/g).length || 0;
var bodylength = body.length + utf8overLoad ;
req.setHeader('Content-length', bodylength);    
0

, .

, writtent nodeJS, urt8 ( "Lucida Console" ), . :

var express = require('express');

var app = express()
  .use(express.methodOverride())
  .use(express.bodyParser())
  .post('/rpc', function(req, res) {
    console.log(JSON.stringify(req.body, null, 2));
    res.send(req.body.x);
  };

app.listen(8080);

( express@3.4.8)

:

{
   "x": ""
}

:

var request = require('request');

request.post({
  uri:'http://localhost:8080/rpc',
  json:{"x": ""}
}, function(err, res, body) { 
   console.log(body); 
});

( request@2.21.0)

:

NodeJS 0.10.4

HTTP-, curl, "Advanced REST Client".

But the important thing is that the request is sent with the encoding "application / json" (and not the classic x-www-form-urlencoded) and that the middleware bodyParser()on the server performs JSON deserialization.

0
source

All Articles