Как поймать статус 503 в тампермонкее - PullRequest
0 голосов
/ 02 октября 2018

У меня есть скрипт пользователя, который обновляет страницу каждую секунду, но иногда веб-сайт, который он пытается обновить, сталкивается с ошибкой состояния 503, и это больше не позволяет скрипту работать.Это означает, что скрипт больше не будет пытаться обновлять страницу каждую секунду.Как сохранить работоспособность скрипта после того, как страница перешла в статус 503 ошибка?В консоли ошибка выглядит следующим образом:

Не удалось загрузить ресурс: сервер ответил со статусом 503 (служба недоступна)

// ==UserScript==
// @name        script
// @namespace   name
// @description example
// @match       *^https://example.com/$*
// @version     1
// @require     https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @grant       GM_xmlhttpRequest
// @run-at document-end
// ==/UserScript==

//*****************************************START OF SET_TIMEOUT
var timeOne = 1000;
var theTime = timeOne;

var timeout = setTimeout("location.reload(true);", theTime);
function resetTimeout() {
clearTimeout(timeout);
timeout = setTimeout("location.reload(true);", theTime);
} //end of function resetTimeout()
//*****************************************END OF SET_TIMEOUT

Ответы [ 3 ]

0 голосов
/ 09 октября 2018

Пользовательский скрипт запускается при загрузке страницы, он не будет работать, если страница вообще не загружается для любого кода состояния, кроме 200. Вы можете использовать <iframe>, как предложено @Hemanth, но вам нужно разорвать бесконечный циклкак <iframe> также загрузит пользовательский скрипт и так далее.Чтобы сломать его, просто проверьте, загружен ли пользовательский скрипт в верхнем окне.

if (window == window.top) {
    // Remove everything from the page
    // Add an iframe with current page URL as it's source
    // Add an event to reload the iframe few seconds after it is loaded
}

Полный код:

(function ($) {
  'use strict';
  var interval = 5000;
  if (window == window.top) {
    var body = $('body').empty();
    var myframe = $('<iframe>')
      .attr({ src: location.href })
      .css({ height: '95vh', width: '100%' })
      .appendTo(body)
      .on('load', function () {
        setTimeout(function () {
          myframe.attr({ src: location.href });
        }, interval);
      });
  }
})(jQuery);
0 голосов
/ 10 октября 2018

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

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

Вот пример сценария пользователя, который обновляет домашнюю страницу StackOverflow каждые 10 секундс новым HTML.Вы можете использовать DOMParser для преобразования текста ответа в документ, по которому можно перемещаться с помощью querySelector, среди прочего:

// ==UserScript==
// @name         Update SO
// @namespace    CertainPerformance
// @version      1
// @match        https://stackoverflow.com/
// @grant        none
// ==/UserScript==

const container = document.querySelector('.container');
function getNewData() {
  console.log('getting new data');
  fetch('https://stackoverflow.com',
    {
      // The following is needed to include your existing cookies with the request, which may be needed:
      credentials: "same-origin"
    })
    .then((resp) => {
      // If there are errors, such as a 503 error, proceed directly to the `finally` to try again:
      if (!resp.ok) return;
      return resp.text();
    })
    .then((text) => {
      const doc = new DOMParser().parseFromString(text, 'text/html');
      container.innerHTML = doc.querySelector('.container').innerHTML;
    })
    .finally(() => {
      // Whether there was an error or not, try to refresh again in a few seconds:
      setTimeout(getNewData, 10000);
    });
}

setTimeout(getNewData, 10000);
0 голосов
/ 08 октября 2018

Простое решение, о котором я могу подумать, - это переместить реальную веб-страницу, которую необходимо обновлять каждую секунду, в другой фрейм или в какой-либо HTML-контейнер, и используя свой пользовательский скрипт, вы можете обновить или перезагрузить этот контейнер с HTML-страницей, которую вы хотите обновить.

Если вы не делаете http-запрос на загрузку веб-страницы из своего скрипта, возможно, не удастся обработать http-ошибки (я могу ошибаться!).Ваш пользовательский сценарий должен находиться на уровне надмножества, где он будет иметь контроль или область действия даже после каких-либо 503 или любых подобных ошибок HTTP.

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

Надеюсь, это поможет ..

...