Попробуйте и откройте этот URL в своем браузере https://httpstat.us/404 или, другими словами, посмотрите, что произойдет, когда вы выберетеэта конечная точка (URL)с помощью JavaScript (пример кода ниже).

const fetch = require('node-fetch');
fetch('https://httpstat.us/404')
    .then(function(){
      console.log('200 OK');
    }).catch(function(){
      console.console.log('404 Not Found');
    })

Итак, если вы знакомы с основами любого API/веб-программирования, вы уже догадались, что приведенный выше код должен быть напечатан в консоли.

404 Not Found

Так что, если вы догадались, что это `404`, как и я, когда я впервые использовал JavaScript `fetch()` API, это неверно!

Поскольку JavaScript API fetch() был разработан не так.

Итак, ответ 😕

200 OK

Краткий обзор функции fetch()

fetch() Вызов API или fetch() метод для простоты в этой статье — это один из многих доступных современных способов отправки сети запроситьи получить информацию (или ответ) от сервера (или конечной точки).

Метод fetch() возвращает Promise, поэтому вы можете использовать методы then() и catch() для его обработки. Для простоты думайте о Promise как о ответе на ваш запрос.

✅ Интересно знать, что вы можете вызывать метод fetch() различными способами, например, но не ограничиваясь этим:

1. Пример API запроса GET с функцией fetch()

const fetch = require('node-fetch');
let url = 'https://google.com';
fetch(url, {
    method: 'GET',
    headers: {
      Accept: 'application/json',
    }
  })
  .then(function() {
    console.log('Okay Google - 200');
  }).catch(function() {
    console.log('Google-  not so OK');
  });

2. Упрощенный: пример API запроса GET с fetch()

const fetch = require('node-fetch');
fetch('https://www.google.com')
  .then(function() {
    console.log('Okay Google - 200');
  }).catch(function() {
    console.log('Google-  not so OK');
  });

3. Пример API запроса POST с fetch()

const fetch = require('node-fetch');
fetch('https://www.google.com', {
  method: 'POST',
  headers: {
    Accept: 'application/json',
  }
}).then(function() {
  console.log('Okay Google - 200');
}).catch(function() {
  console.log('Google-  not so OK');
});

4. Еще один пример API запроса POST с fetch() {аккуратный пример}

let requestData = {
  method: 'POST',
  body: data,
  headers: new Headers()
}
fetch(url, requestData)
  .then(function() {
    // here you can handle the response provided by server
  });

К настоящему времени, если бы вы не знали, вы бы знали, что означают 200 и 404, но не в полном смысле. В обоих случаях этих знаний достаточно, чтобы продолжить чтение.

Из официальной документации MDN (по состоянию на февраль 2021 г.)

The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.

Да как вы только что прочитали, 200 за 400, 404, 4хх, 3хх и так далее и тому подобное…. все пройдет нормально

Также вы заметили, что это значит, когда говорят:

... 
and it will only reject on network failure or if anything prevented the request from completing.

Чтобы проверить это, я запустил приведенный ниже код, чтобы получить URL-адрес с отключенным интернетом 📵, чтобы посмотреть, что произойдет.

Итак, я прервал написание этой статьи и перешел к практическому кодированию ⌨️

вот что произошло — вуаля FetchError !

Google-  not so OK
FetchError: request to https://google.com/ failed, reason: getaddrinfo ENOTFOUND google.com
    at ClientRequest.<anonymous> (C:\node_modules\node-fetch\lib\index.js:1461:11)
    at ClientRequest.emit (events.js:315:20)
    at TLSSocket.socketErrorListener (_http_client.js:469:9)
    at TLSSocket.emit (events.js:315:20)
    at emitErrorNT (internal/streams/destroy.js:106:8)
    at emitErrorCloseNT (internal/streams/destroy.js:74:3)
    at processTicksAndRejections (internal/process/task_queues.js:80:21) {
  type: 'system',
  errno: 'ENOTFOUND',
  code: 'ENOTFOUND'
}

Скриншот опыта на терминале.

Итак, до сих пор мы знаем, что такое выборка, что такое 200 and 4xx и когда и как вы можете добраться до блока catch() метода fetch().

Большой вопрос все еще открыт, как мне обрабатывать ответы 3xx, 4xx и 5xx при использовании fetch() .

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

Итак, вот пример кода. просто следуйте цифрам, чтобы понять, как работает код в режиме реального времени.

const fetch = require('node-fetch');
fetch('https://httpstat.us/404') 1️⃣ 
    .then(function(response) { 2️⃣ 
        if (!response.ok) { 3️⃣ 
            throw Error(response.statusText);4️⃣ 
        }
        return response;
    }).then(function(response) {
        console.log('200 - ok');
    }).catch(function(error) { 5️⃣ 
        console.log('404 Not Found : '+ error); 6️⃣ 
    });

Это выдаст ошибку и, следовательно, попадет в 5️⃣ catch()️⃣блок, и это будет напечатано в консоли.

404 Not Found : Error: Not Found 

теперь мы знаем, как отлавливать 404 любой другой статус ошибки, такой как 406, 500, 503.... почему бы не улучшить код элегантным способом для обработки любой такой ошибки

function manageErrors(response) { 3️⃣ //input promise by fetch()
  if (!response.ok) { 4️⃣
    throw Error(response.statusText);5️⃣
  }
  return response;
}
let url = 'https://httpstat.us/503'; // pass your URL here
fetch(url) 1️⃣
  .then(manageErrors) 2️⃣ // call function to handle errors
  .then(function(response) {
    console.log('200 - ok');
  }).catch(function(error) { 6️⃣
    console.log(error); 7️⃣
  });

если вы являетесь поклонником выражения стрелочной функции (ES6), используйте меньше строк кода

.function manageErrors(response) { 3️⃣
  if (!response.ok) {   4️⃣
    throw Error(response.statusText);   5️⃣
  }
  return response;
}
let url = 'https://...'; // pass your URL here 
fetch(url) 1️⃣
  .then(manageErrors) 2️⃣
  .then(response => console.log('200 - ok'))
  .catch(error => console.log(error)); 6️⃣

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

function manageErrors(response) { 
    if (!response.ok) { 
           if (response.status == 404){ 
                  throw Error(response.statusText); 
            }
           return ; // will print '200 - ok'
     }
    return response;
}

А что, если вы хотите, чтобы код диапазона ошибок был перехвачен, а затем обработан?

function manageErrors(response) {
  if (!response.ok) {
    if (response.status >= 200 && response.status < 300) {
      throw Error(response.statusText);
    }
    return; // will print '200 - ok'
  }
  return response;
}

Подождите, что, если вы хотите, чтобы и код состояния ошибки, и сообщение об ошибке передавались обратно, чтобы вы могли обрабатывать все типы не200 ?

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

function manageErrors(response) { 3️⃣ 
    if(!response.ok){ 4️⃣
          const responseError = { 5️⃣️
               statusText: response.statusText,
               status: response.status
          };
          throw(responseError); 6️⃣
    }
    return response;
}
fetch('https://httpstat.us/503')  1️⃣ 
    .then(manageErrors)  2️⃣ // call function to handle errors
    .then(function(response) {
        console.log('200 - ok');
    }).catch(function(error) { 7️⃣
          console.log('Error Code   : ' + error.status );8️⃣
          console.log('Error Reason : ' + error.statusText);9️⃣
    });

Это напечатает что-то

Error Code   : 503
Error Reason : Service Unavailable

…💡 Подсказка к статье…

  • Загрузите и настройте node js
  • Если вы не можете приступить к выборке и столкнулись с такой проблемой, как:
    fetch('https://www.google.com')
    ^
    ReferenceError: выборка не определена

Это означает, что, вероятно, узел не может найти пакет npm node-fetch, который вы можете установить, выполнив:

npm install node-fetch

➕… Бонусная информация… ➕

Когда запрос завершится, ресурс будет доступен. В это время обещание будет преобразовано в объект Response.

Response из fetch()и в ​​целом предоставляет несколько методов на основе обещаний для доступа к телу в различных форматах, как показано ниже.

  • response.text() — прочитать ответ и вернуться в виде текста
  • response.json() — анализировать ответ как JSON
  • response.formData() — вернуть ответ как объект FormData
  • response.blob() — вернуть ответ как Blob (двоичные данные с типом)
  • response.arrayBuffer() — вернуть ответ в виде ArrayBuffer (низкоуровневое представление двоичных данных)
  • кроме того, response.body является объектом ReadableStream, он позволяет вам читать тело фрагмент за фрагментом.

Подробнее читайте на Официальной странице MDN в Response

Подробнее читайте в других моих историях на Medium.