如何使用 Greasemonkey 从远程域获取 cookie
How to obtain a cookie from a remote domain using Greasemonkey?
我正在编写一个 Greasemonkey (v2.3) 脚本,该脚本基本上对 lema.rae.es/drae/srv/search 提供的内容进行屏幕抓取,因为缺乏任何类型的 API。
问题是,我想从谷歌翻译查询该网址,这是一个不同的域。为此,我可以毫无问题地使用GM_xmlhttpRequest,但是对特定 URL(例如 lema.rae.es/drae/srv/search?val=test)的 GET 请求会产生一个带有隐藏表单的 HTML 页面,该页面在调用 challenge()
javascript 函数后被 POST - 它计算某种在 POST 请求中传递的令牌。
显然,这是异步发生的,Greasemonkey 什么也没看到。通过反复试验,我意识到,如果我的浏览器(Iceweasel 31.2.0)有一个用于 lema.drae.es 的cookie,那么使用GM_xmlhttpRequest
发出的GET请求实际上返回了我想要的,这是作为URL中的参数"val"传递的单词定义的HTML。但是,如果我删除 lema.drae.es 的所有 cookie,GET 请求将返回上述隐藏形式。
简而言之,我需要一种方法来接收来自 Greasemonkey 内部的 POST 请求的响应,我相信如果可以从服务器接收 cookie 并将其存储,那么我可以将其作为请求标头包含在进一步的请求中,它应该按我预期工作。或者它应该简单地存储在浏览器中,因此当我触发GM_xmlhttpRequest
时会作为标头发送。
尝试了另一种解决方案来解决我的问题,即使用隐藏的 iframe,但浏览器以同源策略为由阻止了此类 iframe 的创建,即使在将用户脚本配置为在两个域上运行之后也是如此。
希望我已经明确了我想要实现的目标,我希望有人能为我指出正确的方向。
附带说明一下:如果有人能解释challenge()
函数的计算结果,我将不胜感激。我的假设是,它生成的令牌被发送到服务器,服务器又使用它来生成cookie,但这听起来过于复杂了......
隐藏的iframe路由是要走的路,但在这种情况下,它被 translate.google.com 阻止了。
这里有一种替代方法,以确保 Firefox 拥有保持您的混搭网站 (lema.rae.es) 满意所需的新鲜 cookie:
-
查找一些源 HTML,当混搭网站需要新鲜的 cookie 时存在,否则不存在。
在这种情况下,JS 源function challenge
就可以了。 -
将
GM_xmlhttpRequest
到混搭网站并测试响应。 -
如果GM_xmlhttpRequest响应具有所需的数据,请根据需要对其进行解析。
做! -
如果GM_xmlhttpRequest响应具有"需要 Cookie"源,请在弹出窗口中打开混搭网站的特殊查询:
- 由于站点在其自己的窗口中打开,因此不会被跨源保护措施阻止。
- 将 GM 脚本设置为也在此特殊 URL 上运行。
- 对于特殊 URL,请等待,直到存在指示页面已完成加载并设置 cookie 的关键节点或文本。
- 弹出窗口完成后,它会向打开页面发送一条消息,然后自行关闭。
- 当打开页面收到消息时,它会重新GM_xmlhttpRequests混搭页面。
- 解析并完成!
这是一个完整且经过测试的(在 Firefox 上)Greasemonkey 脚本,可以将 lema.rae.es/drae/srv/search 混入 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 + '"'
);
}
- 在put方法之前从作用域获取数据
- Javascript从字符串中获取顶级域
- 在没有jsonp的情况下从另一个域获取数据(json格式)
- 如何使用 Greasemonkey 从远程域获取 cookie
- 从另一个域获取iframe的内容
- 如何从iframe跨域获取内容
- 如何使用ajax jsonp将数据从一个域获取到另一个域
- AngularJS:Can't将变量的值从ctrl作用域获取到指令中
- 从另一个域获取用户验证cookie
- 跨域获取iframe javascript内部的iframe属性
- 如何使用php和javascript从不同的域获取cookie
- 正在跨域获取iframe当前src url
- 动态添加或复制指令不会从父作用域获取变量值
- 如何使用JQuery正确地从跨域获取xml
- 从外部作用域获取函数参数计数
- 从同一域获取Json数据,如何使用asp.NET从另一个域获取Json数据
- 从指令中的独立作用域获取作用域变量
- 如何使用jQuery从另一个域获取JSON
- CORS,想要从不同的域获取 JSON
- 使用隔离作用域获取隐藏按钮的属性