我想在Firefox/Greasemonkey用户脚本中检索一个HTML页面作为document
。
编辑:这不是跨域请求。
这是我的示例代码:
var r = new XMLHttpRequest();
r.open("GET", document.location.href, true);
r.responseType = "document";
r.send(null);
这看起来就像中的示例https://developer.mozilla.org/en/HTML_in_XMLHttpRequest,但是CCD_ 2引起CCD_。原因,而不是投掷!在try...catch
中换行不会改变任何内容,它看起来像是回调或事件处理程序引发了异常:
TypeError: document.location is null
回溯引用的是Firefox内部的event.js
文件,但不是我的脚本。
删除设置responseType
的行可以消除异常,添加回调则不能。但是,响应是有效的,并且responseXML
提供了DOM树。我使用的是FF 13.0.1。
我是错过了什么,还是这是个bug?
解决方案:这与Mozilla的Addon Builder创建的扩展有关,而不是Firefox。
脚本正在(此外,问题代码不是google.com
上运行,您正在尝试获取google.de
,对吗?这是一个跨域请求XMLHttpRequest
的有效同步或异步使用。)
要在Greasemonkey脚本(或Chrome)中执行跨域(或不执行)AJAX,请使用GM_xmlhttpRequest()
请注意,GM_xmlhttpRequest()
当前不允许您指定responseType
,但在这种情况下您不需要这样做。如果您想要一个好的解析文档,请使用DOMParser
。
综合起来:
GM_xmlhttpRequest ( {
method: 'GET',
//url: 'https://www.google.de/',
url: location.href, // self get, checking for updates
onload: function (respDetails) {
processResponse (respDetails);
}
} );
function processResponse (respDetails) {
// DO ALL RESPONSE PROCESSING HERE...
var parser = new DOMParser ();
var doc = parser.parseFromString (respDetails.responseText, "text/html");
//--- Example showing that the doc is fully parsed/functional...
console.log (doc.querySelectorAll ("p") );
}
PS:由于这毕竟不是跨域的,更正的原始代码将是:
var r = new XMLHttpRequest();
r.onload = function () {
// DO ALL RESPONSE PROCESSING HERE...
console.log (this.response.querySelectorAll ("div") );
}
r.open ("GET", location.href, true);
r.responseType = "document";
r.send (null);
用于异步请求。
不幸的是,您无法从一个域到另一个域执行Ajax:
http://en.wikipedia.org/wiki/Same_origin_policy
你可以阅读CORS:
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
或JSONP作为可能的解决方案:
http://en.wikipedia.org/wiki/JSONP
然而,浏览器的设计方式使得人们不能只是在域之间随机创建Ajax请求,因为这是一个安全问题。
如果你绝对需要从不同的域获取内容,我会考虑使用cURL创建你自己的服务器API,在同一个域上提供你自己的内容,然后在那里使用Ajax。否则,你将不得不看看谷歌是否会授予CORS访问权限,或者是否有某种内置的JSONP请求。