如何在注入代码中使用 GM_xmlhttpRequest? [英] How to use GM_xmlhttpRequest in Injected Code?

查看:19
本文介绍了如何在注入代码中使用 GM_xmlhttpRequest?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个注入网页的用户脚本.该脚本从网络服务器读取一些数据,我想将消息发送到侦听应用程序以对数据做出反应.

I am writing a userscript that is injected into a webpage. The script reads some data from a web-server and I want to send messages to a listening application to react to the data.

现在,我所做的只是尝试向我的侦听应用程序发送一个字符串命令,看看我是否可以读取它.我的代码在注入之前工作,但之后我收到未定义的引用错误".

For now, all I'm doing is trying to send a string command to my listening application and see if I can read it. My code worked before it was injected, but afterwards I get an "undefined reference error".

我怀疑这与这个 Greasemonkey 访问冲突"有关.但是,我一直无法找到有效的解决方案.我正在 Chrome 中开发.

I suspect that this has something to do with this "Greasemonkey access violation". However, I have been unable to find a solution that works. I'm developing in Chrome.

这是我无法开始工作的代码部分.

Here is the section of code I can't get to work.

GM_xmlhttpRequest({
   method: "POST", 
   url: "http://localhost:7777", 
   data: "testing123",
   headers:  {
         "Content-Type": "application/x-www-form-urlencoded"
             },
   onload: function(response) 
   {
      if (response.responseText.indexOf("TEST") > -1) 
      {
         console.log("Response confirmed..."); 
      }
   }
}); 

我对脚本编写还很陌生,所以也许我遗漏了一些明显的东西.我如何让它在注入的代码中工作?

I'm pretty new to scripting so maybe I'm missing something obvious. How do I get this to work in injected code?

推荐答案

GM_ 函数在注入的代码中不起作用,因为注入的代码在目标页面的范围内运行.如果他们确实在那里工作,那么不道德的网站也可以使用GM_功能——做无法形容的邪恶.

GM_ functions will not work in injected code because injected code runs in the target page's scope. If they did work there, then unscrupulous web-sites could also use the GM_ functions -- to do unspeakable evil.

解决方案,最可取的:

  1. 不要注入代码.很多时候,它真的没有必要,而且它总是使事情复杂化.仅当您绝对需要使用目标页面加载的某些 javascript 时才注入代码.

  1. Don't inject code. Much of the time, it really isn't necessary, and it always complicates things. Only inject code if you absolutely, positively need to use some of the javascript loaded by the target page.

对于像 jQuery 这样的库,您可以使用 @require 指令 (Firefox) 或粘贴库代码或使用 自定义manifest.json 文件以包含它(Chrome).

For libraries like jQuery, you will get better performance using the @require directive (Firefox), or pasting-in the library code or using a custom manifest.json file to include it (Chrome).

通过不注入代码,您:

  1. 保持轻松使用GM_功能的能力
  2. 避免或减少对外部服务器的依赖来交付库.
  3. 避免潜在的副作用和对页面 JS 的依赖.(您甚至可以使用诸如 NoScript 之类的东西来完全禁用页面的 JS,而您的脚本仍在运行.)
  4. 防止恶意网站利用您的脚本访问GM_ 功能.

  1. Keep the ability to easily use GM_ functions
  2. Avoid or reduce the dependency on outside servers to deliver libraries.
  3. Avoid potential side effects and dependencies with/on the page's JS. (You could even use something like NoScript to completely disable the page's JS, while your script still runs.)
  4. Prevent malicious web sites from exploiting your script to gain access to the GM_ functions.

  • 使用Tampermonkey 扩展程序 (Chrome).这允许您通过提供更好的 Greasemonkey 模拟来避免脚本注入.您可以使用 @require 指令和比 Chrome 本身提供的更强大/风险更高的 unsafeWindow 版本.

  • Use the Tampermonkey extension (Chrome). This allows you to avoid script injection by providing better Greasemonkey emulation. You can use the @require directive and a more powerful/risky version of unsafeWindow than Chrome natively provides.

    将您的用户脚本代码拆分为注入部分——不能使用 GM_ 函数——和非注入部分.使用消息传递、轮询和/或特定的 DOM作用域之间进行通信的节点.

    Split your userscript code into injected parts -- which cannot use GM_ functions -- and non-injected parts. Use messaging, polling, and/or a specific DOM node to communicate between the scopes.

    <小时><小时>

    如果您真的必须使用注入代码,这里有一个示例脚本,展示了如何做到这一点:



    If you really must use injected code, here's a sample script that shows how to do it:

    // ==UserScript==
    // @name        _Fire GM_ function from injected code
    // @include     https://stackoverflow.com/*
    // @grant       GM_xmlhttpRequest
    // ==/UserScript==
    /* Warning:  Using @match versus @include can kill the Cross-domain ability of
        GM_xmlhttpRequest!  Bug?
    */
    
    function InjectDemoCode ($) {
        $("body").prepend ('<button id="gmCommDemo">Open the console and then click me.</button>');
    
        $("#gmCommDemo").click ( function () {
            //--- This next value could be from the page's or the injected-code's JS.
            var fetchURL    = "http://www.google.com/";
    
            //--- Tag the message, in case there's more than one type flying about...
            var messageTxt  = JSON.stringify (["fetchURL", fetchURL])
    
            window.postMessage (messageTxt, "*");
            console.log ("Posting message");
        } );
    }
    
    withPages_jQuery (InjectDemoCode);
    
    //--- This code listens for the right kind of message and calls GM_xmlhttpRequest.
    window.addEventListener ("message", receiveMessage, false);
    
    function receiveMessage (event) {
        var messageJSON;
        try {
            messageJSON     = JSON.parse (event.data);
        }
        catch (zError) {
            // Do nothing
        }
        console.log ("messageJSON:", messageJSON);
    
        if ( ! messageJSON) return; //-- Message is not for us.
    
        if (messageJSON[0] == "fetchURL") {
            var fetchURL    = messageJSON[1];
    
            GM_xmlhttpRequest ( {
                method:     'GET',
                url:        fetchURL,
                onload:     function (responseDetails) {
                                // DO ALL RESPONSE PROCESSING HERE...
                                console.log (
                                    "GM_xmlhttpRequest() response is:
    ",
                                    responseDetails.responseText.substring (0, 80) + '...'
                                );
                            }
            } );
        }
    }
    
    function withPages_jQuery (NAMED_FunctionToRun) {
        //--- Use named functions for clarity and debugging...
        var funcText        = NAMED_FunctionToRun.toString ();
        var funcName        = funcText.replace (/^functions+(w+)s*((.|
    |
    )+$/, "$1");
        var script          = document.createElement ("script");
        script.textContent  = funcText + "
    
    ";
        script.textContent += 'jQuery(document).ready( function () {' + funcName + '(jQuery);} );';
        document.body.appendChild (script);
    };
    

    这篇关于如何在注入代码中使用 GM_xmlhttpRequest?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆