node.js и utf-8 в данных POST - PullRequest
       0

node.js и utf-8 в данных POST

8 голосов
/ 18 октября 2011

У меня проблемы с декодированием строк UTF-8 в данных POST при использовании веб-сервера Node.JS.

См. Полный тестовый пример:

require("http").createServer(function(request, response) {

  if (request.method != "POST") {

    response.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
    response.end('<html>'+
      '<head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head>'+
      '<body>'+
      '<form method="post">'+
      '<input name="test" value="Grüße!"><input type="submit">'+
      '</form></body></html>');

  } else {

    console.log("CONTENT TYPE=",request.headers['content-type']);

    var body="";
    request.on('data', function (data) {
      body += data;
    });

    request.on('end', function () {
      console.log("POST BODY=",body);

      response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
      response.end("POST DATA:\n"+body+"\n---\nUNESCAPED:\n"+unescape(body)+
        "\n---\nHARDCODED: Grüße!");
    });

  }

}).listen(11180);

Это автономный веб-сервер, который прослушивает порт 11180 и отправляет HTML-страницу в простой форме, которая содержит поле ввода со специальными символами. Отправка этой формы на сервер отобразит ее содержимое в виде простого текстового ответа.

Моя проблема в том, что специальные символы не отображаются должным образом ни на консоли, ни в браузере. Вот что я вижу как с FireFox, так и с IE:

POST DATA:
test=Gr%C3%BC%C3%9Fe%21
---
UNESCAPED:
test=GrüÃe!
---
HARDCODED: Grüße!

Последняя строка - это жестко закодированная строка Grüße!, которая должна соответствовать значению поля ввода (чтобы убедиться, что это не проблема отображения). Очевидно, что данные POST не интерпретируются как UTF-8. Та же проблема возникает при использовании require('querystring') для разбивки данных на поля.

Любая подсказка?

При использовании Node.JS v0.4.11 в Debian Linux 4 исходный код сохраняется в кодировке utf-8

1 Ответ

5 голосов
/ 18 октября 2011

Символы UTF-8 üß не найдены в кодировке ascii и представлены несколькими символами ascii.

Согласно http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1

Тип контента "application / x-www-form-urlencoded" неэффективен для отправки больших количеств двоичных данных или текста, содержащего символы не ASCII . Тип содержимого "multipart / form-data" должен быть используется для отправки форм, которые содержат файлы, данные не в формате ASCII и двоичные данные.

Переключение вашего enctype в форме на multipart <form method="post" enctype="multipart/form-data />" будет корректно отображать текст как символы UTF-8. Затем вам нужно разобрать составной формат. node-formidable , кажется, самая популярная библиотека для этого.

Вероятно, гораздо проще использовать decodeURIComponent(), как вы упомянули в комментарии. Unescape не обрабатывает многобайтовые символы и вместо этого представляет каждый байт как свой собственный символ, отсюда и искажение, которое вы видите. http://xkr.us/articles/javascript/encode-compare/

Вы также можете использовать буферы для изменения кодировки. В этом случае перебейте, но если вам нужно:

new Buffer(myString, 'ascii').toString('utf8');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...