2017-02-22 10 views
0

Я использую Fetch API для загрузки некоторых JSON. Поэтому я использую .json() в потоке ответа, а также необязательный второй аргумент функции (onRejected) в .then(), который имеет только один аргумент - причина отклонения.Отклоненная выборка: доступ к тексту ответа

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

Рассмотрим упрощенный фрагмент:

fetch('api.php') 
.then(
    response => { return response.json(); } 
) 
.then(
    json => { /* useful fulfillment value, a JSON object */ }, 
    reason => { /* string message only */ } 
); 

Если API отвечает что-то другое, чем действительный JSON, он будет отвергать со следующей причине:

SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

Хотя это совершенно ясно, сообщение об ошибке , ему не хватает дампа того, что на самом деле вызвало ошибку.

Я рассмотрел использование .text(), а затем попытался самостоятельно разобрать JSON, но это несколько противоречит цели .json().

Есть ли разумный способ получить доступ к тексту ответа, если отклонение потока считается отклоненным?

ответ

0

Вы можете проверить тип содержимого:

var contentType = response.headers.get("content-type"); 
    if(contentType && contentType.indexOf("application/json") !== -1) { 
     response => { return response.json(); } 
    } 
    else{ 
     response => { return response.text(); } 
    } 

Если вы хотите, чтобы получить ответ на отклонения обратного вызова вы можете сделать что-то вроде этого

response => { 
      var text = ''; 
      try{ 
       text= response.json(); 
      } 
      catch (e if e instanceof SyntaxError) { 
      text = response.text(); 
      } 
      return text; 
    } 
+1

Это был бы простой и безопасный способ обеспечения ответа на обработку, но для этого потребовалось бы проверить, действительно ли аргумент * был * JSON. Я мог бы сразу использовать '.text()'.Вопрос в том, есть ли способ получить доступ к ответу в обратном вызове отказа. – dakab

+1

Как насчет try..catch, как указано выше? – cjds

+1

Вы пробовали? Он по-прежнему вызывает функцию отклонения, вероятно, потому, что переназначение не происходит после того, как поток ответа был прочитан до завершения. – dakab

0

Допустим, это отвратительно, но может решить проблему:

let res; 
fetch('api.php') 
.then(
    response => { res = response; return response.json(); } 
) 
.then(
    json => { /* useful fulfillment value, a JSON object */ }, 
    reason => { /* use res variable */ } 
); 
0

Если ответ определенно имеет тело, то прочитайте текст, используя метод response.text() (как показано в других ответах или в другом месте: MDN, Google Web), затем проанализируйте его до или после любых дополнительных условий или проверок (например, это JSON? затем используйте JSON.parse).

Использование тела не является эффективным методом для обработки ошибок. Что происходит в тех случаях, когда API не включает тело, или он неверен, или запрос полностью завершен? Вместо этого посмотрите на response.statusText (например, «Не найдено»), response.status (например, 404) и другие заголовки. Или в случаях, когда выборка не срабатывает, ответом будет объект Error с error.message и error.stack. Если у вас есть API и требуется более сложный/предсказуемый обмен сообщениями, подумайте о добавлении пользовательских заголовков, таких как «специальное сообщение», и получите его с чем-то вроде if(response.headers) response.headers.get('special-message').

Работайте только с телом, как только эти другие сценарии не будут иметь проблемы с большей предсказуемостью. Вышеупомянутые заголовки также доступны до завершения любой потоковой передачи для дальнейшего упрощения и улучшения реагирования и реагирования.

Смежные вопросы