如何在返回响应之前获取 AJAX 获取请求以等待页面呈现? [英] How to get an AJAX get-request to wait for the page to be rendered before returning a response?

查看:28
本文介绍了如何在返回响应之前获取 AJAX 获取请求以等待页面呈现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为


但是,它实际上应该包含来自 Site2 的搜索结果的完整内容,如下所示:


我尝试了同步 Ajax 请求以及 GM_xmlhttpRequest 都无济于事.

这是站点 2 有问题的进度条:


在将响应返回给 Site1 之前,如何让 AJAX 请求等待 Site2 上的搜索完全呈现?

作为参考,起初看起来像这样:

然后就这样结束了:


以下脚本:

  1. 在隐藏的 iframe 中加载资源页面.
  2. 启动在 iframe 页面上运行的第二个实例.
  3. 等待 iframe 页面完成,根据需要处理结果.
  4. 将所需的负载数据发送到在目标(母版)页面上运行的 GM 脚本.
  5. 目标页面的脚本然后插入有效负载数据以完成混搭.

//==UserScript==//@name _Cross-site, AJAX 抓取演示//@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//==/用户脚本==如果 (/fiddle.jshell.net/i.test (location.host)) {console.log ("***主页面开始...");/*--- 通知用户.*/$("#plainResults").before ('<div id="gmFetchRez">Greasemonkey 正在从 jsbin.com 获取结果...</div>');/*--- 设置以处理来自 iFrame 上运行的 GM 实例的消息:*/window.addEventListener("message", receiveMessage, false);/*--- 在隐藏的 iframe 中加载资源站点.*/$("body").append('<iframe src="http://jsbin.com/ahacab" id="gmIframe"></iframe>');}别的 {console.log ("***帧开始...");/*--- 等待 AJAXed-in 内容...*/waitForKeyElements ("#results table.rezTable", sendResourcePageData);}函数 sendResourcePageData (jNode) {console.log ("找到结果!将它们发送到主窗口...");window.top.postMessage (jNode.html(), "*");}函数接收消息(事件){if (event.origin != "http://jsbin.com") 返回;$("#gmFetchRez").html (event.data);}//--- 使用 CSS 控制外观.GM_addStyle ( " #gmIframe { 显示:无;} #gmFetchRez { 背景:浅黄色;边框:3px双红;填充:1em;} ");

<小时>

最终结果如下所示,脚本已安装并运行:

I am in the process of writing a Greasemonkey Script for pages in this site (Site1). Site1 has deals and offers of various kinds and my GM script aims to do the following:

When one visits an offer on Site1, the script queries Site2 to find out whether this hotel is also listed on Site2. If so, display the search results from Site2 on Site1.

The problem is that Site2 displays a progress bar ("Loading Results") and then displays the results. Thus my Ajax request always returns empty results and looks like this (See the red-boxed portion):


However, it should actually have the complete contents of the search results from Site2, like so:


I have tried a synchronous Ajax request as well as GM_xmlhttpRequest to no avail.

This is the problematic progress bar of Site 2:


How can I get the AJAX request to wait for the the search on Site2 to be completely rendered before returning the response to Site1?

For reference, my complete working script code is at pastebin.com.

This is the relevant snippet:

$(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');  
});

解决方案

In order for the AJAX get to "wait for the page to be rendered", it would actually have to fully process the page, fetching and running all the included CSS and javascript files. That's not easy and not recommended. Fortunately, you don't need to do that anyway.

Here are three better ways to approach this kind of problem:

  1. The resource page (mpdining.rewardsnetwork.com, for this question) might have an API. If it does, find it and use it. This is your best bet, if it's available.

  2. Analyze the resource page's javascript and/or AJAX requests. Use GM_xmlhttpRequest() to directly fetch just the payload data, instead of trying to parse the resource page.

    Sometimes this process is fairly easy, but some sites require complex interaction and/or authentication.

  3. Load the resource page in a hidden iframe; set your Greasemonkey script to run on both the resource page and the master page and to relay the desired data using postMessage().

    This approach will almost always work, although you may have to prevent some pages from attempting to "bust out" of the iframe.



Using a hidden iframe to get data from a cross-domain, resource page:

Greasemonkey scripts will run on both a normal page and on pages within iframes. In fact, you can set the same script to run on both, and on multiple domains.

If a master page and an iframed resource page are both running GM script(s), the script instances can communicate with each other, cross-domain, using postMessage().

For example, suppose we have a site, fiddle.jshell.net/9ttvF/show, that contains travel data, and we want to mash-up that site with matching data from a resource site, jsbin.com/ahacab, that uses AJAX to get its payload data.

The target (master) site looks like this:

The resource site looks like this at first:

Then finishes like this:


The following script:

  1. Loads the resource page in a hidden iframe.
  2. Starts a second instance of itself running on the iframed page.
  3. Waits for the iframed page to finish, processing the results as desired.
  4. Sends the desired payload data to the GM script running on the target (master) page.
  5. The target-page's script then inserts the payload data to complete the mash-up.

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


The final result looks like this, with the script installed and running:

这篇关于如何在返回响应之前获取 AJAX 获取请求以等待页面呈现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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