How to catch status 503 in tampermonkey

元气小坏坏 提交于 2019-12-01 04:36:56

问题


I have a userscript that refreshes the page every second, but sometimes the website it's trying to refresh runs into the status 503 error, and that stops the script from running anymore. That means that script will no longer try refresh the page every second. How do I keep the script running after the page runs into the status 503 error? The error looks like this in the console:

Failed to load resource: the server responded with a status of 503 (Service Unavailable)

// ==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

回答1:


The user-script run at page load, they won't run if page does not load at all for any status code other than 200. You can use <iframe> as @Hemanth suggested but you have to break the infinite loop as the <iframe> will also load the user-script and so on. To break it just check if the user-script is loaded on the top window.

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
}

Complete Code:

(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);



回答2:


Simple solution I could think of is to move the actual webpage that need to be refreshed every second to another frame or some HTML container and using your user script you could refresh or reload that container with the HTML page you want to refresh.

Unless you are making a http request to load webpage from your script it may not be possible to handle the http errors (I might be wrong!). Your user script should be at a superset level where it will have control or scope even after any 503 or any similar HTTP errors.

You could use Page state change events to ensure or to check to refresh the page in the frame/container has loaded or not to avoid reloading the webpage before it loads. Unless if you want to reload irrespective of webpage successfully loaded or not.

Hope this helps..




回答3:


The problem is that location.reload attempts to completely replace the page with a reloaded version, but if the browser fails to connect to the server, the page will not be loaded, and any userscripts for that page will fail to run, because there's no page for them to run on.

A workaround would be to use a Javascript network request to fetch the text of the new page, and then replace the existing content with the new content with Javascript - if the response is a 503 error (or some other error), you can simply ignore it and try again. This ensures that you'll always stay on the same (loaded) page, so the userscript will continue running indefinitely, even if the responses sometimes fail.

Here's an example of a userscript that updates StackOverflow's homepage every 10 seconds with new HTML. You can use DOMParser to transform response text into a document that can be navigated with querySelector, among other things:

// ==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);


来源:https://stackoverflow.com/questions/52613406/how-to-catch-status-503-in-tampermonkey

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!