2012-06-19 52 views
2

我想覆蓋XMLHttpRequest的發送,以便讓我的腳本知道數據何時通過這樣的請求在頁面上更新。我重寫代碼如下所示:爲什麼不支持XMLHttpRequest的Chrome unsafeWindow技巧發送覆蓋?

var oldSend = unsafeWindow.XMLHttpRequest.prototype.send; 

unsafeWindow.XMLHttpRequest.prototype.send = function(){ 
    console.log("notified of XHR update"); 
    oldSend.apply(this, arguments); 
} 

如果我注入到這個頁面(W/O的unsafeWindow引用)它工作正常,但我希望得到這個從userscript範圍工作。 unsafeWindow適用於Firefox,但不適用於Chrome。所以我搶Brock Adams' nifty trick to create a working unsafeWindow in Chrome

var bGreasemonkeyServiceDefined  = false; 

try { 
    if (typeof Components.interfaces.gmIGreasemonkeyService === "object") { 
     bGreasemonkeyServiceDefined = true; 
    } 
} 
catch (err) { 
    //Ignore. 
} 

if (typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined) { 
    unsafeWindow = (function() { 
     var dummyElem = document.createElement('p'); 
     dummyElem.setAttribute ('onclick', 'return window;'); 
     return dummyElem.onclick(); 
    })(); 
} 

但是,當我結合起來兩個什麼都沒有發生。它將所有作品粘貼到控制檯中,但從腳本運行時不會出現錯誤或輸出。我做錯了什麼,或者這超出了這個技巧的能力?

嗯,只是嘗試了一些更簡單的,如:unsafeWindow.document.title = 'testing';,這也不起作用,所以也許它不是特定於XMLHttpRequest

我試圖避免注入頁面,如果可能的話。

回答

1

此:

/*--- Create a proper unsafeWindow object on browsers where it doesn't exist 
    (Chrome, mainly). 
    Chrome now defines unsafeWindow, but does not give it the same access to 
    a page's javascript that a properly unsafe, unsafeWindow has. 
    This code remedies that. 
*/ 
var bGreasemonkeyServiceDefined  = false; 

try { 
    if (typeof Components.interfaces.gmIGreasemonkeyService === "object") { 
     bGreasemonkeyServiceDefined = true; 
    } 
} 
catch (err) { 
    //Ignore. 
} 

if (typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined) { 
    unsafeWindow = (function() { 
     var dummyElem = document.createElement('p'); 
     dummyElem.setAttribute ('onclick', 'return window;'); 
     return dummyElem.onclick(); 
    })(); 
} 

其次是這樣的:

unsafeWindow.document.title = 'testing'; 

工作只是從我的測試userscripts罰款。

這些也行繼unsafeWindow招:

unsafeWindow.foo = function() { 
    console.log ("In foo()."); 
}; 

unsafeWindow.alert = function (s) { 
    console.log ("Alert: ", s); 
}; 

(在一個頁面裏的腳本運行,進入控制檯產量foo():「在富()alert()不產生一個彈出,但打印到控制檯)。

我不知道爲什麼(還)是覆蓋XMLHttpRequest.prototype.send不象是在Chrome userscript工作,但我不建議unsafeWindow方法˚F或者無論如何。

注入覆蓋代碼。如果您沒有(或不能)注入整個腳本,則使用postMessage()(也適用於Chrome)以在頁面範圍和腳本範圍之間進行通信。

+0

brock,thx爲'postMessage()'建議。我試圖避免注入代碼,部分原因是已經閱讀了關於該主題的優點/缺點列表(http://stackoverflow.com/a/10828021/348496)---主要是爲了保護腳本免於關閉或被主機站點阻止。聽起來像你建議注射不管?我會看'postMessage()'並且重新考慮我是否應該只注入它。 – mix

+1

對於Chrome和這種事情,注入是最好的。 'unsafeWindow'實際上可以像注入JS一樣容易被阻塞,但是你總是佔據站點的上風。然而,'unsafeWindow'會爲惡意網站獲得提升的特權打開一個潛在渠道。注射不。 ......就我個人而言,我還沒有需要任何東西,但是對於一個頁面的JS來說,最簡單的訪問(很少)。大多數人希望腳本攔截AJAX的實際情況,只需通過輪詢更改的內容即可得到更好的服務。這可以完全保留在安全的沙箱中。 –

+0

如果我可以在沒有任何注入JS的情況下工作,那麼這仍然是最好的選擇嗎?還是不值得額外的麻煩(調試等)? – mix