7

このサイト(Site1)のページ用のGreasemonkeyスクリプトを作成中です。Site1にはさまざまな種類の取引やオファーがあり、私のGMスクリプトは次のことを目的としています。

Site1のオファーにアクセスすると、スクリプトは Site2にクエリを実行して、このホテルがSite2にもリストされているかどうかを確認します。その場合は、Site2の検索結果をSite1に表示します。

問題は、Site2が進行状況バー(「結果の読み込み」)を表示してから、結果を表示することです。したがって、私のAjaxリクエストは常に空の結果を返し、次のようになります(赤いボックスの部分を参照):(
クリックすると拡大画像が表示されます)未完成の結果


ただし、実際には、次のように、Site2からの検索結果の完全なコンテンツが含まれている必要があります:(
クリックすると拡大画像が表示されます)完成した結果


同期Ajaxリクエストを試しましたがGM_xmlhttpRequest、役に立ちませんでした。

これは、サイト2の問題のあるプログレスバーです
(クリックすると拡大画像が表示されます)ステータスバー


Site1に応答を返す前に、Site2での検索が完全にレンダリングされるのを待つようにAJAXリクエストを取得するにはどうすればよいですか?

参考までに、私の完全に機能するスクリプトコードはpastebin.comにあります。

これは関連するスニペットです:

$(document).ready(function(){   
var rewardsSiteResults = $('<div class="panel deal-panel rc-lr"></div>').attr('id', "rewardsSiteResults")
        .html("<p>" + progressMessageText + "</p> ").append(spinnerGif);
$(insertSelector).after(rewardsSiteResults);

var addressMap = getAddressOfHotel();
var pinCode = addressMap[pinCodePlaceHolder];
var hotelName = addressMap[hotelNamePlaceHolder];
var queryURL = constructQueryURL(pinCode, hotelName);

$.ajaxSetup({async:true, timeout: 5000});
$.get(queryURL,null, function(response) {
    if(!displayed){
        displayed=true;
        //rewardsSiteResults.html("adfaasddsf");
        var text = $(response).find("#col2");
        $(text).find("script").remove();

        //console.log(text.html())
//          $('<iframe id="someId"/>').appendTo('#rewardsSiteResults')
//          .contents().find('body').append(response);
        rewardsSiteResults.html("<div class='panel deal-panel rc-lr'>" + text.html() +"</div>");
        //console.log(response);
    }
},'html');  
});
4

1 に答える 1

11

AJAXが「ページがレンダリングされるのを待つ」ためには、実際にはページを完全に処理し、含まれているすべてのCSSファイルとjavascriptファイルをフェッチして実行する必要があります。それは簡単ではなく、お勧めできません。幸いなことに、とにかくそれを行う必要はありません。

この種の問題に取り組むための3つのより良い方法は次のとおりです。

  1. リソースページ(この質問の場合はmpdining.rewardsnetwork.com)にAPIが含まれている場合があります。もしそうなら、それを見つけて使用してください。利用可能な場合、これが最善の策です。

  2. リソースページのjavascriptやAJAXリクエストを分析します。GM_xmlhttpRequest()リソースページを解析するのではなく、ペイロードデータのみを直接フェッチするために使用します。

    このプロセスはかなり簡単な場合もありますが、一部のサイトでは複雑な対話や認証が必要です。

  3. 非表示のiframeにリソースページを読み込みます。リソースページとマスターページの両方で実行し、を使用して目的のデータを中継するように、Greasemonkeyスクリプトを設定しますpostMessage()

    このアプローチはほとんどの場合機能しますが、一部のページがiframeから「バストアウト」しようとするのを防ぐ必要がある場合があります。



非表示のiframeを使用して、クロスドメインのリソースページからデータを取得します。

Greasemonkeyスクリプトは、通常のページとiframe内のページの両方で実行されます。実際、同じスクリプトを両方と複数のドメインで実行するように設定できます。

マスターページとiframedリソースページの両方がGMスクリプトを実行している場合、スクリプトインスタンスは、を使用してクロスドメインで相互に通信できますpostMessage()

たとえば、旅行データを含むサイトfiddle.jshell.net/9ttvF/showがあり、そのサイトを、AJAXを使用するリソースサイトjsbin.com/ahacabからの一致するデータとマッシュアップしたいとします。ペイロードデータを取得します。

ターゲット(マスター)サイトは次のようになります。
ターゲットサイト

リソースサイトは、最初は次のようになります。
リソースサイト、開始

次に、次のように終了します。 リソースサイト、終了


次のスクリプト:

  1. 非表示のiframeにリソースページを読み込みます。
  2. iframedページで実行されているそれ自体の2番目のインスタンスを開始します。
  3. iframedページが終了するのを待ち、必要に応じて結果を処理します。
  4. ターゲット(マスター)ページで実行されているGMスクリプトに目的のペイロードデータを送信します。
  5. 次に、ターゲットページのスクリプトがペイロードデータを挿入して、マッシュアップを完了します。
// ==UserScript==
// @name     _Cross-site, AJAX scrape demo
// @include  http://fiddle.jshell.net/9ttvF/show/
// @include  http://jsbin.com/ahacab*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==

if (/fiddle\.jshell\.net/i.test (location.host) ) {
    console.log ("***Master-page start...");

    /*--- Inform the user.
    */
    $("#plainResults").before (
        '<div id="gmFetchRez">Greasemonkey is fetching results from jsbin.com...</div>'
    );

    /*--- Setup to process messages from the GM instance running on the iFrame:
    */
    window.addEventListener ("message", receiveMessage, false);

    /*--- Load the resource site in a hidden iframe.
    */
    $("body").append ('<iframe src="http://jsbin.com/ahacab" id="gmIframe"></iframe>');
}
else {
    console.log ("***Framed start...");
    /*--- Wait for the AJAXed-in content...
    */
    waitForKeyElements ("#results table.rezTable", sendResourcePageData);
}

function sendResourcePageData (jNode) {
    console.log ("Results found!  Sending them to the main window...");

    window.top.postMessage (jNode.html(), "*");
}

function receiveMessage (event) {
    if (event.origin != "http://jsbin.com")     return;

    $("#gmFetchRez").html (event.data);
}

//--- Use CSS to control appearances.
GM_addStyle ( "                                 \
    #gmIframe {                                 \
        display:            none;               \
    }                                           \
    #gmFetchRez {                               \
        background:         lightYellow;        \
        border:             3px double red;     \
        padding:            1em;                \
    }                                           \
" );

スクリプトをインストールして実行すると、最終結果は次のようになります。 マッシュアップ結果

于 2012-07-15T04:33:07.503 に答える