Мое приложение node.js смоделировано как приложение express / examples / mvc .
В действии контроллера я хочу выдать статус HTTP 400 с помощью настраиваемого HTTP-сообщения. По умолчанию сообщение о состоянии http - «Плохой запрос»:
HTTP/1.1 400 Bad Request
Но я хочу отправить
HTTP/1.1 400 Current password does not match
Я пробовал разные способы, но ни один из них не установил сообщение о состоянии http для моего собственного сообщения.
Моя текущая функция контроллера решения выглядит так:
exports.check = function( req, res) {
if( req.param( 'val')!=='testme') {
res.writeHead( 400, 'Current password does not match', {'content-type' : 'text/plain'});
res.end( 'Current value does not match');
return;
}
// ...
}
Все работает нормально, но ... похоже, это не правильный способ.
Есть ли лучший способ установить сообщение о состоянии http с помощью экспресс?
Ответы:
Вы можете проверить эту документацию
res.send(400, 'Current password does not match')
Look express 3.x для получения подробной информацииОБНОВЛЕНИЕ для Expressjs 4.x
Используйте этот способ (смотрите Документы Express 4.x ):
res.status(400).send('Current password does not match'); // or res.status(400); res.send('Current password does not match');
источник
res.status(400).send('Current password does not match');
примерExpress ^4.16.2
Ни один из существующих ответов не выполняет то, что изначально запрашивал OP, а именно переопределение фразы-причины по умолчанию (текст, появляющийся сразу после кода состояния), отправляемой Express.
Вы хотите
res.statusMessage
. Это не часть Express, это свойство базового объекта http.Response в Node.js 0.11+.Вы можете использовать это так (проверено в Express 4.x):
function(req, res) { res.statusMessage = "Current password does not match"; res.status(400).end(); }
Затем используйте,
curl
чтобы убедиться, что он работает:$ curl -i -s http://localhost:3100/ HTTP/1.1 400 Current password does not match X-Powered-By: Express Date: Fri, 08 Apr 2016 19:04:35 GMT Connection: keep-alive Content-Length: 0
источник
statusMessage
отличное от стандартного сообщения, сопоставленного с StatusCoderes.nativeResponse.statusMessage
На стороне сервера (промежуточное ПО Express):
if(err) return res.status(500).end('User already exists.');
Обработка на стороне клиента
Угловой: -
$http()..... .error(function(data, status) { console.error('Repos error', status, data);//"Repos error" 500 "User already exists." });
jQuery: -
$.ajax({ type: "post", url: url, success: function (data, text) { }, error: function (request, status, error) { alert(request.responseText); } });
источник
Один из элегантных способов обработки таких пользовательских ошибок в экспрессе:
function errorHandler(err, req, res, next) { var code = err.code; var message = err.message; res.writeHead(code, message, {'content-type' : 'text/plain'}); res.end(message); }
(для этого вы также можете использовать встроенный express.errorHandler )
Затем в вашем промежуточном программном обеспечении перед вашими маршрутами:
Тогда где вы хотите создать ошибку «Текущий пароль не совпадает»:
function checkPassword(req, res, next) { // check password, fails: var err = new Error('Current password does not match'); err.code = 400; // forward control on to the next registered error handler: return next(err); }
источник
Вы можете использовать это так
return res.status(400).json({'error':'User already exists.'});
источник
Мой вариант использования - отправка настраиваемого сообщения об ошибке JSON, поскольку я использую экспресс для работы моего REST API. Я думаю, что это довольно распространенный сценарий, поэтому остановлюсь на нем в своем ответе.
Укороченная версия:
Экспресс-обработка ошибок
app.use(function(err, req, res, next) { if (err instanceof JSONError) { res.status(err.status).json({ status: err.status, message: err.message }); } else { next(err); } });
Вызвать ошибки в любом месте кода, выполнив:
var JSONError = require('./JSONError'); var err = new JSONError(404, 'Uh oh! Can't find something'); next(err);
Длинная версия
Канонический способ выдачи ошибок:
var err = new Error("Uh oh! Can't find something"); err.status = 404; next(err)
По умолчанию Express обрабатывает это, аккуратно упаковывая его как HTTP-ответ с кодом 404 и телом, состоящим из строки сообщения, к которой добавлена трассировка стека.
Это не работает для меня, например, когда я использую Express в качестве REST-сервера. Я хочу, чтобы ошибка отправлялась обратно как JSON, а не как HTML. Я также определенно не хочу, чтобы моя трассировка стека передавалась моему клиенту.
Я могу отправить JSON в качестве ответа
req.json()
, например, используя . что-то вродеreq.json({ status: 404, message: 'Uh oh! Can't find something'})
. При желании я могу установить код состояния с помощьюreq.status()
. Сочетание двух:req.status(404).json({ status: 404, message: 'Uh oh! Can't find something'});
Это работает как шарм. Тем не менее, я нахожу довольно громоздким вводить каждый раз, когда у меня есть ошибка, и код больше не самодокументируется, как наш
next(err)
. Это выглядит слишком похоже на то, как отправляется обычный (т.е. действительный) ответ JSON. Кроме того, любые ошибки, вызванные каноническим подходом, по-прежнему приводят к выводу HTML.Именно здесь на помощь приходит промежуточное ПО для обработки ошибок Express. В рамках своих маршрутов я определяю:
app.use(function(err, req, res, next) { console.log('Someone tried to throw an error response'); });
Я также подклассифицирую Error в собственный класс JSONError:
JSONError = function (status, message) { Error.prototype.constructor.call(this, status + ': ' + message); this.status = status; this.message = message; }; JSONError.prototype = Object.create(Error); JSONError.prototype.constructor = JSONError;
Теперь, когда я хочу выдать ошибку в коде, я делаю:
var err = new JSONError(404, 'Uh oh! Can't find something'); next(err);
Возвращаясь к промежуточному программному обеспечению для пользовательской обработки ошибок, я изменяю его на:
app.use(function(err, req, res, next) { if (err instanceof JSONError) { res.status(err.status).json({ status: err.status, message: err.message }); } else { next(err); } }
Создание подкласса Error в JSONError важно, поскольку я подозреваю, что Express
instanceof Error
проверяет первый параметр, переданный в a,next()
чтобы определить, нужно ли вызывать нормальный обработчик или обработчик ошибок. Я могу удалитьinstanceof JSONError
проверку и внести незначительные изменения, чтобы непредвиденные ошибки (например, сбой) также возвращали ответ JSON.источник
При использовании Axios вы можете получить собственное ответное сообщение с помощью:
Axios.get(“your_url”) .then(data => { ... do something }.catch( err => { console.log(err.response.data) // you want this })
... после установки его в Express как:
res.status(400).send(“your custom message”)
источник
Если ваша цель - просто сократить его до одной / простой строки, вы можете немного полагаться на значения по умолчанию ...
return res.end(res.writeHead(400, 'Current password does not match'));
источник
Что ж, в случае Restify мы должны использовать
sendRaw()
методСинтаксис:
res.sendRaw(200, 'Operation was Successful', <some Header Data> or null)
источник