如何在坦帕猴子中捕获状态503

时间:2018-10-02 17:26:19

标签: javascript error-handling settimeout tampermonkey http-status-code-503

我有一个用户脚本,它每秒刷新一次页面,但是有时它试图刷新的网站出现状态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 :(得分:1)

用户脚本在页面加载时运行,如果页面根本没有加载200以外的任何状态代码,则它们将不会运行。您可以按{Hemanth的建议使用<iframe>,但必须中断<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);

答案 1 :(得分:0)

我能想到的简单解决方案是将需要每秒刷新的实际网页移动到另一个框架或某个HTML容器,并使用您的用户脚本可以刷新或重新加载要刷新的HTML页面的容器。

除非您正在发出http请求以从脚本加载网页,否则可能无法处理http错误(我可能错了!)。您的用户脚本应处于超集级别,即使在发生任何503或任何类似的HTTP错误之后,该脚本也将具有控制权或作用域。

您可以使用页面状态更改事件来确保或检查是否刷新了已加载框架/容器中的页面,以避免在加载页面之前重新加载该页面。除非您要重新加载而不考虑网页是否成功加载。

希望这会有所帮助。

答案 2 :(得分:0)

问题是location.reload试图用重新加载的版本完全替换该页面,但是如果浏览器无法连接到服务器,则该页面将不会加载,并且该页面的任何用户脚本都将无法加载运行,因为没有页面可运行。

一种解决方法是使用Javascript网络请求来获取新页面的文本,然后用Javascript将现有内容替换为新内容-如果响应是503错误(或其他错误),则说明可以简单地忽略它,然后再试一次。这样可以确保您始终停留在同一(已加载)页面上,因此即使响应有时失败,用户脚本也将无限期运行。

这是一个用户脚本示例,该脚本每10秒使用新的HTML更新一次StackOverflow的主页。您可以使用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);