7

私はウェブページに注入されたuserscriptを書いています。スクリプトはウェブサーバーからいくつかのデータを読み込み、リッスンするアプリケーションにメッセージを送信してデータに反応させたいと考えています。注射されたコードでGM_xmlhttpRequestを使用するには?

今のところ、私がしていることは、リスニングアプリケーションに文字列コマンドを送信して、それを読むことができるかどうかを確認しようとしていることです。私のコードは注入される前に動作しましたが、その後は "未定義の参照エラー"が発生します。

これはこの"Greasemonkey access violation"と関係があると思われます。しかし、私は解決策を見つけることができませんでした。私は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..."); 
     } 
    } 
}); 

私は非常にスクリプトに新しく、多分私は何かが明らかに欠けている。これを注入されたコードで動作させるにはどうすればよいですか?

+0

Chromeバージョンは?あなたのメタデータブロック( '= = UserScript ==')を表示できますか? –

+0

私はそれをクローム用に開発しています。私はそれを配布したり何もしていない。今のところ自分でやっているだけなので、メタデータは意味を持ちません。 – akagixxer

答えて

15

GM_注入されたコードがターゲットページの有効範囲で実行されるため、注入されたコードでは機能しません。もし彼らがで働かせれば、悪意のあるWebサイトでも機能を使うことができます。

ソリューション、最も好ましい最初は:

  1. コードを挿入しないでください。多くの場合、実際には必要ではなく、常に複雑なものになります。もしあなたが絶対に、目的のページによってロードされたjavascriptのいくつかを積極的に使う必要がある場合にのみ、コードを注入してください。

    @requireディレクティブ(Firefox)を使用するか、ライブラリコードを貼り付けたり、a custom manifest.json file(Chrome)を使用してパフォーマンスを向上させます。コードを注入しないことにより

    、あなたは:

    1. は、簡単にライブラリを提供するために外部のサーバへの依存を避けるか、または減らすGM_機能
    2. を使用する能力を保ちます。
    3. ページのJSとの潜在的な副作用や依存関係を避けてください。 (NoScriptのようなものを使用しても、スクリプトが実行されている間は、ページのJSを完全に無効にすることができます)
    4. GM_の機能に悪意のあるWebサイトが悪用されないようにします。

  2. 使用the Tampermonkey extension(クローム)。これにより、より良いGreasemonkeyエミュレーションを提供することによりスクリプト注入を回避できます。 @requireディレクティブを使用し、より強力で危険なバージョンのunsafeWindowをChromeがネイティブに提供するものよりも使用できます。

  3. ユーザーコードコードを注入部分に分割します(GM_の機能は使用できません)。 messaging、ポーリング、特定の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)+$/, "$1"); 
    var script   = document.createElement ("script"); 
    script.textContent = funcText + "\n\n"; 
    script.textContent += 'jQuery(document).ready(function() {' + funcName + '(jQuery);});'; 
    document.body.appendChild (script); 
}; 
+0

ありがとう!これは十分に仕事をして物事を把握しました。私は注射されたコードを使用する必要があります。将来的に私はより洗練されたソリューションを見つけることを望みますが、Webスクリプティングについての限られた知識があれば、今のところうまくいくはずです。 – akagixxer

関連する問題