1

我想document在 Firefox/Greasemonkey 用户脚本中检索 HTML 页面。

编辑:不是跨域请求。

这是我的示例代码:

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中的示例,但r.send(null)会导致TypeError. 原因,而不是抛出!将行包装在 atry...catch不会改变任何东西,似乎回调或事件处理程序引发了异常:

TypeError: document.location is null

回溯指的是 Firefox 内部event.js文件,但不是我的脚本。

删除设置responseType摆脱异常的行,添加回调不会。但是,响应是有效的并responseXML提供了一个 DOM 树。我正在使用 FF 13.0.1。

我错过了什么还是这是一个错误?

解决方案:这与 Mozilla 的 Addon Builder 创建的扩展有关,而不是 Firefox。

4

2 回答 2

2

脚本正在运行google.com,您正在尝试 fetch 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);

对于异步请求。

于 2012-07-19T08:32:28.387 回答
0

不幸的是,您不能从一个域到另一个域执行 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。否则,您将不得不查看 Google 是否会授予 CORS 访问权限或具有某种内置的 JSONP 请求。

于 2012-07-19T08:06:49.900 回答