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

问题描述 投票:1回答:1
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文档中是可行的,除非从站点调用它即可。

javascript html node.js userscripts tampermonkey
1个回答
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 user-script.
      document.getElementById('test-btn').addEventListener('click', ev => testFunction());
    </script>
  </body>
  </html>

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

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

您需要inject脚本到页面中,以使其也可用于页面的脚本。例如。您可以动态创建一个<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

© www.soinside.com 2019 - 2024. All rights reserved.