Javascript Fetch иногда возвращает 404 - PullRequest
0 голосов
/ 12 апреля 2019

Мы обнаруживаем, что иногда наша команда .fetch возвращает 404. Даже если файл существует и регулярно просматривается, иногда он получает 404.

window.fetch('/category/somepage', {
    credentials: 'same-origin',
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(app.addAntiForgeryToken(postData))
  })
  .then(function(response) {
    if (response.ok) {
      return response.json();
    }
    throw new Error('Network response was not ok');
  })
  .then(result => {
    if (result.Status === 'OK') {
      //...
    }
  })

В данный момент его ловят с помощью throw new Error.

Поскольку нам нужно решить эту проблему, каков наилучший способ принудительно повторить попытку, пока страница не будет нажата? Должны ли мы показать кнопку для повтора или есть способ сделать это? Я не уверен, почему это привело бы к 404, поскольку файл определенно существует все время.

1 Ответ

3 голосов
/ 12 апреля 2019

Классическая вещь, которую нужно сделать здесь, это повторить операцию, потому что сетевая связь может быть ненадежной, особенно на мобильных устройствах. Но переходные процессы 404 - это другая проблема, и они указывают на проблему с веб-сервером, которая может потребовать отдельной диагностики. (Например: если это кластер веб-серверов, действующих как одна конечная точка, один из них может быть неправильно настроен и, следовательно, не найдет ресурс, который могут найти остальные).

Но для кратковременных сбоев классическая вещь - это повтор:

function fetchJSONWithRetry(input, init, retries = 10) {
    return fetch(input, init)
        .then(function(response) {
            if (response.ok) {
                return response.json();
            }
            throw new Error('Network response was not ok'); // I usually use `new Error("HTTP status " + response.status)`
        })
        .catch(error => {
            if (retries <= 0) {
                throw error;
            }
            return fetchJSONWithRetry(input, init, retries - 1);
        });
}

используется так:

fetchJSONWithRetry('/category/somepage', {
    credentials: 'same-origin',
    method: 'POST',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(app.addAntiForgeryToken(postData))
})
.then(result => {
    if (result.Status === 'OK') {
        // ...
    }
})
.catch(error => {
    // All retries failed, handle it
});

(input и init - это имена , используемые в спецификации для fetch, так что я использовал это выше.)

...