如何使用Greasemonkey从远程域获取cookie? [英] How to obtain a cookie from a remote domain using Greasemonkey?

查看:325
本文介绍了如何使用Greasemonkey从远程域获取cookie?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写一个Greasemonkey(v2.3)脚本,该脚本基本上屏蔽了 lema.rae.es/drae/srv/search ,因为缺少任何类型的API。

I'm writing a Greasemonkey (v2.3) script that basically screen-scrapes the contents served by lema.rae.es/drae/srv/search, for lack of an API of any sort.

事情是,我想从其他网域的Google翻译中查询该网址。为此,我可以使用GM_xmlhttpRequest没有问题,但GET请求到特定的URL(例如 lema.rae.es/drae/srv/search?val=test )生成一个带有隐藏表单的HTML页面,在调用 challenge()之后获取POSTed javascript函数 - 它计算在POST请求中传递的某种类型的令牌。

The thing is, I want to query that URL from Google Translate, a different domain. For that, I can use GM_xmlhttpRequest without problems, but a GET request to a specific URL (for instance lema.rae.es/drae/srv/search?val=test) yields an HTML page with a hidden form that gets POSTed after calling the challenge() javascript function -- which calculates some sort of token which gets passed along in the POST request.

显然,这是异步发生的,Greasemonkey看不到任何东西。通过尝试和错误我已经认识到,如果我的浏览器(Iceweasel 31.2.0)有一个cookie的lema.drae.es,然后使用 GM_xmlhttpRequest 发出的GET请求返回我想要的,这是在URL中作为参数val传递的单词的定义的HTML。但是,如果我删除了lema.drae.es的所有cookie,GET请求返回上述隐藏的表单。

Obviously, this happens asynchronously and Greasemonkey sees nothing of it. Via trial and error I have come to realise that if my browser (Iceweasel 31.2.0) has a cookie for lema.drae.es, then the GET request issued using GM_xmlhttpRequest actually returns what I want, which is the HTML of the definition of the word passed as a the parameter "val" in the URL. However, if I delete all cookies for lema.drae.es, the GET request returns the aforementioned hidden form.

总之,我需要一种方法来接收响应从Greasemonkey内的POST请求,我相信如果有可能从服务器接收cookie并存储它,然后我可以包括它作为请求头在进一步的请求,它应该按预期工作。或者它应该简单地存储在浏览器中,因此当我触发 GM_xmlhttpRequest 时,将作为标题发送。

In short, I need a way to receive the response of that POST request from within Greasemonkey, and I believe that if it were possible to receive the cookie from the server and store it then I could include it as a request header in a further request and it should work as I expect. Or it should simply be stored in the browser and therefore would get sent as a header when I trigger GM_xmlhttpRequest.

我尝试了一个不同的解决方案,我的问题,即使用隐藏的iframe ,但是这种iframe的创建被浏览器阻止了基于Same Origin策略,即使配置了在两个脚本上运行的userscript域。

I tried a different solution to my problem, namely using a hidden iframe, but the creation of such iframe was blocked by the browser on the grounds of the Same Origin policy, even after configuring the userscript to run on both domains.

希望我明确了我想达到的目标,希望有人能指出我的方向。

Hopefully I've made clear what I want to achieve, and I hope somebody can point me in the right direction.

在旁注:如果有人可以解释 challenge()函数计算, 。我的假设是它生成的令牌发送到服务器,反过来使用它来生成cookie,但听起来如此过于复杂...

On a side note: if someone could explain what the challenge() function calculates, I would really appreciate it. My hypotheses would be that the token it generates gets sent to the server which in turn uses it to produce the cookie, but that sounds so overly complicated...

推荐答案

隐藏的iframe路线是要走的路,但在这种情况下它被 translate.google.com 阻止。

The hidden iframe route is the way to go, but it is being blocked by translate.google.com in this case.

这里是一种替代方法,可确保Firefox拥有保存您的mashup网站所需的新Cookie,( lema。 rae.es )快乐:

Here is an alternate approach to ensure that Firefox has the fresh cookies it needs to keep your mashup site (lema.rae.es) happy:


  1. 查找mashup网站想要新鲜Cookie时出现的源HTML,

    在这种情况下,JS源函数挑战将会执行。

GM_xmlhttpRequest 添加到mashup网站并测试响应。

Make the GM_xmlhttpRequest to the mashup site and test the response.

GM_xmlhttpRequest 响应具有所需数据,根据需要进行解析。

完成!

If the GM_xmlhttpRequest response has the desired data, parse it as desired.
Done!

如果GM_xmlhttpRequest 响应具有需要Cookie来源,在弹出窗口中打开一个特殊查询:

If the GM_xmlhttpRequest response has the "needs cookies" source, open a special query, of the mashup site, in a popup window:


  1. 由于网站在自己的窗口中打开,因此不会被跨源保护措施阻止。

  2. 将GM脚本设置为也在此特殊网址上操作。

  3. 对于特殊网址,请等待指示网页已完成载入并设置Cookie的关键节点或文本,/ /。

  4. 一次

  5. 当开始页面获取消息时,它会重新GM_xmlhttp请求mashup页面。

  6. 解析并完成!

  1. Since the site is opening in it's own window, it won't be blocked by cross-origin safeguards.
  2. Set the GM script to also operate on this special URL.
  3. For the special URL, wait until key nodes, or text, are/is present that indicate that the page has finished loading and cookies are set.
  4. Once the popup has finished, it sends a message to the opening page and then closes itself.
  5. When the opening page gets the message, it re-GM_xmlhttpRequests the mashup page.
  6. Parse it and Done!




这里是完整的测试(在Firefox上)Greasemonkey脚本,将 lema.rae.es/drae/srv/search > translate.google.com 。 :


Here is a complete and tested (on Firefox) Greasemonkey script that mashes lema.rae.es/drae/srv/search into translate.google.com. :

// ==UserScript==
// @name     _GM_xmlhttpRequest that needs cookie(s)
// @include  https://translate.google.com/*
// @include  http://lema.rae.es/drae/srv/search?val=openedByGM
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_xmlhttpRequest
// ==/UserScript==

//--- Global variables
var mashupURL   = "http://lema.rae.es/drae/srv/search?val=test";
var cookGenURL  = "http://lema.rae.es/drae/srv/search?val=openedByGM";

if (location.href == cookGenURL) {
    //--- May be best we can do until Greasemonkey fixes tab handling flaws.
    document.title = "Close me!";

    if (window.opener) {
        waitForKeyElements ("i:contains(openedByGM)", closePopupIfCan);
    }
}
else {
    attemptMashup ();

    window.addEventListener ("message", receiveCookieMessage, false);
}

//-- Just functions from here on down...

function closePopupIfCan (jNode) {
    window.opener.postMessage ("Cookie(s) should be set!", "*");
    window.close ();
}

function attemptMashup () {
    GM_xmlhttpRequest ( {
        method:     "GET",
        url:        mashupURL,
        onload:     parseDictionaryResponse,
        onabort:    reportAJAX_Error,
        onerror:    reportAJAX_Error,
        ontimeout:  reportAJAX_Error
    } );
}

function receiveCookieMessage (event) {
    if (event.origin != "http://lema.rae.es")     return;

    console.log ("message ==> ", event.data);

    /*--- Now that have cookie(s), re-attempt mashup, but need a little
        settling time.
    */
    setTimeout (attemptMashup, 888);
}

function parseDictionaryResponse (respObject) {
    if (respObject.status != 200  &&  respObject.status != 304) {
        reportAJAX_Error (respObject);
        return;
    }
    /*--- If the required cookie is not present/valid, open the target page
        in a temporary tab to set the cookies, then reload this page.

        The test string is unique to the scraped site and is only present
        when cookie(s) is/are needed.
    */
    if (/function\s+challenge/i.test (respObject.responseText) ) {
        var newTab  = window.open (cookGenURL);
        return;
    }

    //--- Don't use jQuery to parse this!
    var parser      = new DOMParser ();
    var responseDoc = parser.parseFromString (
        respObject.responseText, "text/html" // Firefox only, for now.
    );

    //--- Get site-specific payload and put in site-specific location.
    var payload     = responseDoc.querySelectorAll ("body > div");
    $("#gt-form-c").before (payload);
}

function reportAJAX_Error (respObject) {
    alert (
        'Error ' + respObject.status + '!  "' + respObject.statusText + '"'
    );
}

这篇关于如何使用Greasemonkey从远程域获取cookie?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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