当前位置: 首页 > 面试题库 >

如何获得AJAX get-request以等待页面呈现后再返回响应?

卫增
2023-03-14
问题内容

我正在为该站点(Site1)中的页面编写Greasemonkey脚本。Site1提供各种交易和报价,而我的GM脚本旨在实现以下目的:

当一个人访问Site1上的报价时,脚本会查询
Site2,以查找该酒店是否也在Site2上列出。如果是这样,请在Site1上显示来自Site2的搜索结果。

问题是Site2显示进度条(“正在加载结果”),然后显示结果。因此,我的Ajax请求始终返回空结果,并且看起来像这样(请参见红色框部分):(
单击查看大图)未完成的结果

但是,它实际上应该具有Site2的搜索结果的完整内容,如下所示:(
单击以查看大图)完成的结果

我尝试了同步Ajax请求GM_xmlhttpRequest,但无济于事。

这是站点2出现问题的进度条:(
单击查看大图)状态栏

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

作为参考,我完整的工作脚本代码在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');  
});

问题答案:

为了使AJAX“等待页面呈现”,它实际上必须完全处理页面, 获取 并运行
所有包含的CSS和javascript文件。这并不容易,不建议这样做。幸运的是,您仍然不需要这样做。

这是解决此类问题的三种更好的方法:

  1. 资源页面 (mpdining.rewardsnetwork.com,对于这个问题),可能有一个API。如果有,请找到并使用它。如果可以的话,这是您最好的选择。

  2. 分析资源页面的javascript和/或AJAX请求。使用GM_xmlhttpRequest()直接取刚刚有效载荷数据,而不是试图解析资源页面。

有时,此过程相当容易,但是某些站点需要复杂的交互和/或身份验证。

  1. 将资源页面加载到隐藏的iframe中;将您的Greasemonkey脚本设置为在资源页面和母版页面上运行,并使用中继所需的数据postMessage()

尽管您可能必须防止某些页面试图从iframe中“退出”,但是这种方法几乎总是可行的。

使用隐藏的iframe从跨域资源页面获取数据:

Greasemonkey脚本将在普通页面和iframe内的页面上运行。实际上,您可以将同一脚本设置为同时在多个域和两个域上运行。

如果 母版页 和iframed 资源页
都运行GM脚本,则脚本实例可以使用跨域相互通信postMessage()

例如,假设我们有一个网站,fiddle.jshell.net/9ttvF/show,包含旅游数据,我们要
混搭了 该网站与从匹配数据 资源网站
,jsbin.com/ahacab,使用AJAX获得其有效载荷数据。

目标(主)站点如下所示:
目标地点

首先,资源站点如下所示:
资源站点,开始

然后完成如下: 资源站点,完成

以下脚本:

  1. 将资源页面加载到隐藏的iframe中。
  2. 启动本身在iframed页面上运行的第二个实例。
  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; \
    } \
    ” );

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



 类似资料:
  • 有什么想法吗?没有JS库。 编辑:我做了几次回拨尝试。老实说,我很难理解他们。下面是我的最后一次尝试:

  • 问题内容: 我正在使用@ font- face将字体嵌入到我的网站中。首先,文本将作为系统默认值呈现,然后(假定字体文件已加载)正确的字体将在几分之一秒后呈现。有没有一种方法可以通过延迟页面渲染直到加载字体或类似字体之后来最小化/消除此延迟。 问题答案: 这取决于浏览器的行为方式。 首先,您的@font在哪里声明?它是内联到HTML,是在页面上的CSS表中声明,还是(希望)在外部CSS表中声明?

  • 问题内容: 当使用简单的回调(例如下面的示例)时: 如何更改功能以使用异步/等待?具体来说,假设“ someEvent”被保证只能被调用一次,那么我希望函数测试是一个异步函数,该异步函数在执行回调之前不会返回,例如: 问题答案: 不是魔术。异步函数是可以为您解开Promises的函数,因此您需要返回一个Promise才能起作用。像这样: 然后 但这也是一个谎言,因为异步函数也返回Promises本

  • 使用以下示例中的简单回调时: 如何将函数更改为使用异步/等待?具体地说,假设某个事件保证被调用一次并且只有一次,我希望函数测试是一个异步函数,直到执行回调才返回,例如:

  • 如何让一个函数等到它中的一个修改方法得到它的响应后再返回? 我见过很多关于堆栈溢出的问题和答案,但由于愚蠢或我没有完全得到它们。 我有一个视图模型,它给视图一个文本显示在屏幕上。 就像,我确实喜欢这个视图,activity_foo.xml: 并且在视图模型类中: 我想您会得到策略,因为它在MVVM模式中很常见。 所以FooRepository,我的意思是视图模型的真实存储库如下所示: 这是一个通常

  • 我正在尝试使用selenium webdriver+Java+NGWebDriver来自动化一个混合的AngularJS2(2.4.10)web应用程序。