Как использовать GM xmlhttpRequest в вводимом коде?

Я пишу userscript, который вводится на веб-страницу. Скрипт считывает некоторые данные из веб-сервера и я хочу, чтобы отправлять сообщения в приложение, чтобы реагировать на данные.

пока все, что я делаю, это пытаюсь отправить строковую команду в мое прослушивающее приложение и посмотреть, смогу ли я ее прочитать. Мой код работал до того, как он был введен, но впоследствии я получаю "неопределенную ссылочную ошибку".

Я подозреваю, что это имеет какое-то отношение к этому "нарушение доступа Greasemonkey". Однако я не смог найти решение, которое работает. Я развиваюсь в Chrome.

вот раздел кода, который я не могу получить для работы.

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..."); 
      }
   }
}); 

Я довольно новичок в сценариях, поэтому, возможно, я упускаю что-то очевидное. Как я могу заставить это работать в injected коде?

1 ответов


GM_ функции не будут работать в введенном коде, поскольку введенный код выполняется в области целевой страницы. Если они ... --10-->сделал работайте там, тогда недобросовестные веб-сайты также могут использовать GM_ функции -- делать страшное зло.

решения, наиболее предпочтительные сначала:

  1. не вводите код. Большую часть времени это действительно не нужно, и это всегда усложняет ситуацию. Только введите код, если вам абсолютно, положительно нужно чтобы использовать некоторые javascript, загруженные целевой страницей.

    для библиотек, таких как jQuery, вы получите лучшую производительность, используя @require директива (Firefox) или вставка-в код библиотеки или использование таможни манифест.в JSON включить его (Chrome).

    не вводя код, вы:

    1. держите возможность легко использовать GM_ функции
    2. избежать или снизить зависимость от внешние серверы для доставки библиотек.
    3. избегайте потенциальных побочных эффектов и зависимостей с/на JS страницы. (Вы даже можете использовать что-то вроде NoScript чтобы полностью отключить JS страницы, пока ваш скрипт все еще работает.)
    4. предотвратить вредоносные веб-сайты от использования вашего скрипта, чтобы получить доступ к GM_ функции.

  2. использовать в расширение Tampermonkey в (Chrome). Это позволяет избежать инъекции скрипта, обеспечивая лучшую эмуляцию Greasemonkey. Вы можете использовать @require директива и более мощная/рискованная версия unsafeWindow чем Chrome изначально обеспечивает.

  3. разделите код userscript на вводимые части, которые не могут использовать GM_ функции -- и не вводят частями. Использовать сообщения, опрос и / или определенный узел DOM для связи между масштабы.



если вы действительно должны использовать введенный код, вот пример скрипта, который показывает как это сделать:

// ==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:\n",
                                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 (/^function\s+(\w+)\s*\((.|\n|\r)+$/, "");
    var script          = document.createElement ("script");
    script.textContent  = funcText + "\n\n";
    script.textContent += 'jQuery(document).ready( function () {' + funcName + '(jQuery);} );';
    document.body.appendChild (script);
};