2012-07-19 1089 views
1

我想在Firefox/Greasemonkey userscript中檢索HTML頁面,請求爲document當詢問DOM對象時,XMLHttpRequest.send()拋出異常

編輯:這是而不是一個跨域請求。

這裏是我的示例代碼:

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。原因,而不是拋出!包裹在try...catch行不會改變任何東西,這似乎是一個回調或事件處理程序引發異常:

TypeError: document.location is null 

追溯是指一個Firefox內部event.js文件,而不是我的腳本。

刪除行設置responseType擺脫了異常,添加回調沒有。 但是,響應是有效的,並且responseXML提供了一個DOM樹。 我正在使用FF 13.0.1。

我錯過了什麼,或者這是一個錯誤?

解決方案:這與由Mozilla的Addon Builder創建的擴展有關,而不是Firefox。

+0

我在Chrome上遇到以下錯誤: XMLHttpRequest無法加載https://www.google.de/。起源http://fiddle.jshell.net是不允許的Access-Control-Allow-Origin.'似乎很清楚... [示例這裏](http://jsfiddle.net/HTcKP/57/) – ManseUK 2012-07-19 07:51:24

+1

這是一個完全不同的問題。當腳本來自'jshell.net'時,當然對'google.com'的http請求是不允許的。嘗試它作爲一個用戶腳本,這個錯誤將消失。 – 2012-07-19 07:57:21

+1

Firefox中沒有event.js文件。聽起來像你有一些擴展安裝,看着所有的XHRs和螺絲了......什麼是問題event.js文件的完整URI? – 2012-07-20 05:52:03

回答

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請求。

+0

對於誤導性示例代碼,我很抱歉。實際上,我是從腳本的域名請求的。它被設置爲'google.com'的用戶腳本。該請求甚至成功,但在進程中拋出異常。 – 2012-07-19 08:11:16

+0

@trion我的不好。我會仔細看看原來的帖子...... – Stegrex 2012-07-19 08:12:08

+0

@trion怪異的......我可以發誓的位置對象是「window.location」而不是document.location。嘗試使用window.location也許? – Stegrex 2012-07-19 08:14:53

2

腳本在 google.com上運行,您正在嘗試獲取 google.de,對不對?這是一個跨域請求。 (同樣,這個問題的代碼是不是一個有效的同步或者非同步使用XMLHttpRequest

做跨域(或沒有)AJAX中的Greasemonkey腳本(或鉻),使用GM_xmlhttpRequest()
請注意,GM_xmlhttpRequest()目前不允許您指定responseType,但無論如何您無需在此情況下執行此操作。如果你想要一個很好的解析文檔,請使用DOMParser

全部放在一起:

​​




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); 

用於異步請求。

+0

我真的搞砸了那個示例代碼,我很抱歉。這不是一個跨域請求,我調整了原始帖子。 – 2012-07-19 08:50:17

+0

那麼請求'document.location.href'有什麼意義?這是當前頁面,你已經擁有它了!此外,這個答案的代碼將無視工作。 – 2012-07-19 09:15:00

+0

檢查頁面以獲取更新並將其添加到當前視圖,而不刷新整個瀏覽器窗口。 我可以以某種方式在'GM_xmlhttpRequest'中指定'responseType'嗎? – 2012-07-19 09:46:29