Node.js POST вызывает [Ошибка: сокет зависает] код: 'ECONNRESET'

Я создал образец для публикации данных в остальных службах и обнаружил, что когда у меня есть не-ascii или нелатинский символ (см. Data.firstName), мой запрос на публикацию с использованием TEST-REST.js выдает

ошибка: { [Ошибка: сокет зависает] код: 'ECONNRESET' }.

// TEST-REST.js
var http = require('http');

var data = JSON.stringify({
  firstName: 'JoaquÌn',
});

var options = {
  host: '127.0.0.1',
  port: 3000,
  path: '/users',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': data.length
  }
};

var req = http.request(options, function(res) {
  var result = '';

  res.on('data', function(chunk) {
    result += chunk;
  });

  res.on('end', function() {
    console.log(result);
  });
});

req.on('error', function(err) {
  console.log(err);
});

req.write(data);
req.end();

и на моих службах отдыха, это выдает мне ошибку, как это:

SyntaxError: Unexpected end of input Sun Sep 08 2013 23:25:02 GMT-0700 (PDT) -     at Object.parse (native)
    at IncomingMessage.<anonymous> (/Volumes/Data/Program_Data/GitHub/app/node_modules/express/node_modules/connect/lib/middleware/json.js:66:27) info    at IncomingMessage.EventEmitter.emit (events.js:92:17)
    at _stream_readable.js:920:16 : - - - [Mon, 09 Sep 2013 06:25:02 GMT] "POST /users HTTP/1.1" 400 - "-" "-"
    at process._tickDomainCallback (node.js:459:13)

если я заменю значение firstName с JoaquÌn на abc, все будет работать нормально. Я думаю, что мне не хватает чего-то, чтобы поддержать или убежать, чтобы это сработало.

Кто-нибудь есть идеи, как решить эту проблему? Я также попробовал следующее: require ('querystring'). Escape(model.givenName), и это работает, но я не доволен этим.

ОБНОВЛЕНО Я обнаружил, что если я закомментирую: app.use(express.bodyParser());, ошибка исчезнет.

2 ответа

Решение

Это проблема узла, а не проблема экспресса. https://github.com/visionmedia/express/issues/1749

разрешить, изменить с

Content-Length: data.length

в

Content-Length: Buffer.byteLength(данные)

ПРАКТИЧЕСКОЕ ПРАВИЛО

Всегда используйте Buffer.byteLength(), когда вы хотите найти длину содержимого строк

ОБНОВЛЕНО

Мы также должны корректно обрабатывать ошибки на стороне сервера, чтобы предотвратить сбои, добавив промежуточное программное обеспечение для их обработки.

app.use(function (error, req, res, next) {
  if (!error) {
    next();
  } else {
    console.error(error.stack);
    res.send(500);
  }
});

Проблема в том, что если вы не обработаете эту ошибку и не сохраните работоспособность сервера, этот эксплойт может быть использован для атаки DOS. Тем не менее, вы можете справиться с этим и продолжить, и все равно остановить процесс, когда возникают необработанные исключения (что мешает вам работать в неопределенном состоянии - очень плохая вещь).

Модуль подключения обрабатывает ошибку и вызывает next(), отправив обратно объект с телом сообщения и status = 400, В коде вашего сервера вы можете добавить это после express.bodyParser():

var exit = function exit() {
  setTimeout(function () {
    process.exit(1);
  }, 0);
};

app.use(function (error, req, res, next) {
  if (error.status === 400) {
    log.info(error.body);
    return res.send(400);
  }

  log.error(error);
  exit();
});
Другие вопросы по тегам