如何使用tampermonkey在网页上加载外部脚本?

时间:2019-02-03 04:34:59

标签: javascript html node.js userscripts tampermonkey

Calling Script Directly (works)

// ==UserScript==
// @name         Example
// @version      0.1
// @description  Script from a website
// @author       You
// @match        *://*.example.com/*
// @grant        none
// @require      https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js
// @require      https://code.jquery.com/jquery-3.2.1.min.js
// ==/UserScript==

/* script here: */ 

Calling Script Externally (doesn't work)

// ==UserScript==
// @name         Example
// @version      0.1
// @description  Script from a website
// @author       You
// @match        *://*.example.com/*
// @grant        GM_xmlhttpRequest
// @require      https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js
// @require      https://code.jquery.com/jquery-3.2.1.min.js
// @run-at       document-start
// ==/UserScript==

GM_xmlhttpRequest({
    method : "GET",
    url : "http://example.com/script.js",
        onload : (e) => {
        eval(e.responseText);
    }
});

我需要使用tampermonkey将从单独站点存储的JavaScript文件直接加载到网站。将代码直接加载到tampermonkey文档中是可行的,除非从站点调用它。

1 个答案:

答案 0 :(得分:0)

将代码直接加载到tampermonkey文档中是可行的,除非您从站点调用它。

我了解您的陈述,即您试图从页面脚本中调用某些GM加载的函数。

  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Userscript-Test</title>
  </head>
  <body>
    <button id="test-btn">injected script</button>
    <script>
      // invoke testFunction() which is loaded by the userscript.
      document.getElementById('test-btn').addEventListener('click', ev => testFunction());
    </script>
  </body>
  </html>

您的第二个用户脚本实际上确实起作用,但是,如果当前TamperMonkey版本的默认设置不符合same-origin-policy,则会要求用户允许此域的跨域获取。如果允许,您可以通过eval执行该脚本后从用户脚本访问动态加载的脚本。

当然,该脚本在TamperMonkey沙箱中进行评估。因此,您无权访问该页面。

您需要将脚本注入到页面中,以使其也可用于页面的脚本。例如。您可以动态创建一个<script>标签。

// ==UserScript==
// @name         Example
// @version      0.1
// @description  Script from a website
// @author       You
// @match        *://*.example.com/*
// @grant        GM_xmlhttpRequest
// @run-at       document-start
// ==/UserScript==

GM_xmlhttpRequest({
  method : "GET",
  // from other domain than the @match one (.org / .com):
  url : "http://example.org/script.js",
  onload : (ev) =>
  {
    let e = document.createElement('script');
    e.innerText = ev.responseText;
    document.head.appendChild(e);
  }
});

要与较早的用户脚本扩展兼容,您可能需要使用unsafeWindow.document.head@grant unsafeWindow。 (但是,请注意安全性问题。)

您可能还希望@run-at document-start要求扩展名在所有其他脚本之前尽快运行该脚本。在此早期时间,DOM可能尚未准备好。您可以确定DOM准备何时接收注射。请注意,某些插件不能保证用户脚本的实际启动时间。

如果动态加载的脚本不经常更改,请考虑在安装时使用@resource预取它,然后从本地存储中加载它。另请参见GM.getResourceUrl。您可以使用该URL来获取GM_xmlhttpRequest