JQuery AJAX и обработка различных типов данных - PullRequest
10 голосов
/ 12 мая 2009

Я использую ASP.Net MVC, но это относится к любой среде.

Я делаю Ajax-вызов на мой сервер, который большую часть времени возвращает простой старый HTML, однако, если возникает ошибка, я бы хотел, чтобы он возвращал объект JSON с сообщением о состоянии (и некоторые другие вещи). Похоже, для опции dataType в вызове jQuery нет способа справиться с этим хорошо. По умолчанию кажется, что он анализирует все как html, что приводит к заполнению <div> "{ status: 'error', message: 'something bad happened'}".

[Редактировать] Игнорирование объекта dataType и определение jQuery также не работает. Он рассматривает тип результата как string и обрабатывает его как HTML.

Одно из решений, которое я нашел, - попытаться проанализировать объект результата как JSON. Если это работает, мы знаем, что это объект JSON. Если он вызывает исключение, это HTML:

$.ajax({
    data: {},
    success: function(data, textStatus) {
        try {
            var errorObj = JSON.parse(data);
            handleError(errorObj);
        } catch(ex) {
            $('#results').html(data);
        }
    },
    dataType: 'html', // sometimes it is 'json' :-/
    url: '/home/AjaxTest',
    type: 'POST'
});

Тем не менее, использование Исключения таким образом кажется мне довольно плохим дизайном (и, по меньшей мере, не интуитивным). Есть ли способ лучше? Я думал об упаковке всего ответа в объект JSON, но в этом случае я не думаю, что это вариант.

Вот решение, которое я получил от Стива Уилкока:

// ASP.NET MVC Action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AjaxTest(int magic) {
    try {
        var someVal = GetValue();
        return PartialView("DataPage", someVal);
    } catch (Exception ex) {
        this.HttpContext.Response.StatusCode = 500;
        return Json(new { status = "Error", message = ex.Message });
    }
}




// jQuery call:

$.ajax({
    data: {},
    success: function(data, textStatus) {
        $('#results').html(data);
    },
    error: function() {
        var errorObj = JSON.parse(XMLHttpRequest.responseText);
        handleError(errorObj);
    },
    dataType: 'html',
    url: '/home/AjaxTest',
    type: 'POST'
});

Ответы [ 6 ]

9 голосов
/ 12 мая 2009

Для ваших ошибок JSON вы можете вернуть код состояния 500 с сервера, а не 200. Тогда клиентский код jquery может использовать обработчик error: для функции $ .ajax для обработки ошибок. В ответе 500 вы можете проанализировать объект ошибки JSON из responseText, в ответе 200 вы можете просто добавить HTML в div как обычно.

6 голосов
/ 12 мая 2009

Хотя идея Стива хорошая, я добавляю ее для полноты.

Похоже, что если вы укажете тип данных json, но вернете HTML, jQuery прекрасно с этим справится.

Я проверил эту теорию со следующим кодом:

if($_GET['type'] == 'json') {
    header('Content-type: application/json');
    print '{"test":"hi"}';
    exit;
} else {
    header('Content-type: text/html');
    print '<html><body><b>Test</b></body></html>';
    exit;
}

$_GET['type'] только для того, чтобы я мог контролировать, что возвращать во время тестирования. В вашей ситуации вы вернете одно или другое в зависимости от того, все пошло правильно или неправильно. В прошлом, с этим кодом JQuery:

$.ajax({
    url: 'php.php?type=html', // return HTML in this test
    dataType: 'json',
    success: function(d) {
        console.log(typeof d); // 'xml'
    }
});

Несмотря на то, что мы указали JSON в качестве dataType, jQuery (1.3.2) выясняет, что это не так.

$.ajax({
    url: 'php.php?type=json',
    dataType: 'json',
    success: function(d) {
        console.log(typeof d); // 'object'
    }
});

Так что вы можете воспользоваться этим (насколько я знаю) недокументированным поведением, чтобы делать то, что вы хотите.

3 голосов
/ 12 мая 2009

Но почему бы не вернуть только JSON независимо от состояния (успех или ошибка) на POST и использовать GET для отображения результатов?
Кажется, что лучше, если вы спросите меня.

0 голосов
/ 19 мая 2014

Я достиг этого, используя только ajax success и errorbacks. Таким образом, у меня могут быть смешанные строки и ответы объектов json с сервера.

Ниже я готов принять json, но если я получу статус "parsererror" (то есть jquery не сможет проанализировать входящий код как json, поскольку это то, что я ожидал), но он получит статус запроса " ОК "(200), тогда я обрабатываю ответ как строку. Любая вещь, кроме «parsererror» и «OK», я воспринимаю как ошибку.

$.ajax({
    dataType: 'json',
    url: '/ajax/test',
    success: function (resp) {
      // your response json object, see if status was set to error
      if (resp.status == 'error') {
        // log the detail error for the dev, and show the user a fail
        console.log(resp);
        $('#results').html('error occurred');
      }
      // you could handle other cases here
      // or use a switch statement on the status value
    },
    error: function(request, status, error) {
      // if json parse error and a 200 response, we expect this is our string
      if(status == "parsererror" && request.statusText == "OK") {
        $('#results').html(request.responseText);
      } else {
        // again an error, but now more detailed and not a parser error
        // and we'll log for dev and show the user a fail
        console.log(status + ": " + error.message);
        $('#results').html('error occurred');
      }
    }
  });
0 голосов
/ 06 марта 2012

Я столкнулся с точно такой же проблемой с MVC / Ajax / JQuery и хотел использовать несколько типов данных (JSON и HTML). У меня есть запрос AJAX, чтобы использовать HTML dataType для возврата данных, но я пытаюсь преобразовать данные, которые возвращаются из запроса ajax, в объект JSON. У меня есть такая функция, которую я вызываю из моего успешного обратного вызова:

    _tryParseJson: function (data) {
        var jsonObject;

        try {
            jsonObject = jQuery.parseJSON(data);
        }
        catch (err) {
        }

        return jsonObject;
    }

Затем я предполагаю, что если существуют свойства jsonObject и errorMessage, то произошла ошибка, в противном случае ошибка не произошла.

0 голосов
/ 26 августа 2010

Или вы всегда можете вернуть JSON-ответ и иметь один параметр в качестве содержимого HTML.

Что-то вроде:

{
     "success" : true,
     "errormessage" : "",
     "html" : "<div>blah</div>",
}

Я думаю, что вам нужно только избегать двойных кавычек в значении html, и парсер json отменит это для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...