Подтвердить что ты не робот

Как заставить jQuery проанализировать мой ответ на ошибку, представленный как действительный json?

Вот мой код:

      $.ajax({
        url: "/api/invoice/" + newInvoice._id,
        type: 'PUT',
        data: JSON.stringify(newInvoice),
        dataType: 'json',
        contentType: "application/json; charset=utf-8"
      })
        .success(function () {
          $('#statusLine').text('Successfully submitted invoice {0}. Click here to dismiss.'.format(newInvoice._id));
        })
        .error(function (err) {
          alert(err);
        });

Запрос:

PUT http://localhost:8000/api/invoice/16211 HTTP/1.1
Host: localhost:8000
Connection: keep-alive
Content-Length: 770
Origin: http://localhost:8000
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11
Content-Type: application/json; charset=UTF-8
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://localhost:8000/invoice.html?id=16211
Accept-Encoding: gzip,deflate,sdch
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

{"items":[{"id":...

Тело запроса на самом деле является действительным json, я просто укоротил его для краткости.

Ответ:

HTTP/1.1 409 Conflict
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 1386
ETag: 250542419
Connection: keep-alive

{
  "msg": "Cannot update the invoice #16211, because it has already been updated by someone else.",
  "invoice": {
    "items": [
      {...

Опять же, ответ является полностью допустимым json, усеченным для краткости.

Как и ожидалось, обработчик error вызывается с объектом err. Однако, как я могу удержаться на разобранном json? Конечно, я мог проверить, что тип содержимого ответа json и затем проанализировать сам err.responseText, но разве он не должен использоваться для jQuery ajax? Я имею в виду, он делает это для моих запросов $.get, когда я получаю объекты с сервера.

Что мне не хватает?

ИЗМЕНИТЬ

Это исправление для qaru.site/info/289031/...:

Выполнение запроса:

var ajax = $.ajax(...

Обработка ответа об ошибке:

var res, ct = ajax.getResponseHeader("content-type") || '';
if (ct.indexOf('json') > -1) {
  res = $.parseJSON(err.responseText);
  // process the response here
}
4b9b3361

Ответ 1

Для сообщения об ошибке с кодом не-200 1HTTP status, содержимое не будет анализироваться JQuery. Если вам действительно не нравится самостоятельно анализировать полученный результат на JSON, вам нужно будет вернуть статус HTTP 200 и использовать обратные вызовы success (done).

Это хороший признак того, что вы используете (из вашего примера) HTTP-код 409, и я думаю, вам следует продолжать это делать - просто укусите пулю и проанализируйте JSON вручную в обработчике ошибок. Если синтаксический анализ завершился неудачно, что-то еще пошло не так (например, временный сбой сети), но это позволит вам создать хороший API, который вы (и, возможно, другие) можете использовать, не создавая слишком много ошибок при проверке функции успеха.

Сохраните success для счастливых результатов и error для несчастливых результатов.

1 Технически любой 2xx статус должен считаться успешным; в jQuery (status >= 200 && status < 300 || status === 304) считается чем-то успешным.

Ответ 2

Я столкнулся с той же проблемой и нашел несколько отличный ответ от ответа @Barmar.

Как и responseText, существует также свойство responseJSON, поэтому вы можете сделать следующее:

var json_response = err.responseJSON.msg;

Если у вас console.log(err); есть несколько свойств, которые вы можете использовать в своем сообщении об ошибке на странице.

Ответ 3

Вызвать $.parseJSON явно в обратном вызове ошибки:

(...)
.error(function (err) {
  var msg = $.parseJSON(err).msg;
  alert(msg);
});