問題描述
我做了一個 Firefox 擴展來獲取所有請求的 url 并顯示它們.但代碼只有在我將其粘貼到控制臺時才有效.
I make a firefox extension that get all the request url's and displays them. But the code only works if I paste it in the console.
當擴展程序加載時它沒有顯示任何錯誤,它似乎只是不會運行
when the extension loads it doesn't show any error, it seems like it just won't run
這是完整的代碼
xhrScript.js
(function(){
const proxiedOpen = XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function ( _, url) {
this.__URL = url;
return proxiedOpen.apply(this, arguments);
};
const proxiedSend = window.XMLHttpRequest.prototype.send;
window.XMLHttpRequest.prototype.send = function () {
const { protocol, host } = window.location;
// showing only when it paste in console
console.log("full request url ", `${protocol}//${host}${this.__URL}`);
return proxiedSend.apply(this, [].slice.call(arguments));
};
})();
// this works all times
document.body.style.border = "7px solid blue";
ma??nifest.json
{
"manifest_version": 2,
"name": "XHR request urls",
"version": "1.0",
"description": "get all the request url's",
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["xhrScript.js"]
}
]
}
如您所見,最后一行是 document.body.style.border = "7px solid blue";
,每次都可以正常工作.但是 XMLHttpRequest open
和 send
方法不起作用.僅當我將代碼粘貼到控制臺時才有效.
As you can see, in the last line is document.body.style.border = "7px solid blue";
, this works fine every time. But the XMLHttpRequest open
and send
methods don't work. only works if I paste the code in the console.
如果您想查看示例,可以嘗試將 xhrScript.js
代碼復制并粘貼到 https://reactjs.org(這是一個 SPA,所以很容易檢查我想要什么)在 devTools 控制臺中,并查看所有請求.
if you want see an example, you can try copy and paste the xhrScript.js
code in https://reactjs.org (it's a SPA, so it's easy to check what I want) in the devTools console, and see all the request.
我不知道為什么這段代碼只有在控制臺粘貼時才會運行
I don't know why this code only runs when it is pasted in console
推薦答案
內容腳本在隔離的 JavaScript 環境中運行,這意味著 window
及其內容與頁面隔離,因此當您修改它時,您只修改內容腳本的版本.
Content scripts run in an isolated JavaScript environment meaning that window
and its contents are isolated from the page so when you modify it, you only modify the content script's version.
有兩種解決方案:
Firefox 專用.
Firefox-specific.
使用 wrappedJSObject
和 exportFunction
訪問頁面上下文(更多信息):
Use wrappedJSObject
and exportFunction
to access the page context (more info):
const urls = new WeakMap();
const origXhr = hookPagePrototype('XMLHttpRequest', {
open(method, url) {
urls.set(this, url);
return origXhr.open.apply(this, arguments);
},
send() {
console.log('Sending', new URL(urls.get(this), location).href);
return origXhr.send.apply(this, arguments);
},
});
function hookPagePrototype(protoName, funcs) {
const proto = wrappedJSObject[protoName].prototype;
const oldFuncs = {};
for (const [name, fn] of Object.entries(funcs)) {
oldFuncs[name] = exportFunction(proto[name], wrappedJSObject);
proto[name] = exportFunction(fn, wrappedJSObject);
}
return oldFuncs;
}
Chrome 兼容.
Chrome-compatible.
使用 DOM 腳本在頁面上下文中運行代碼:說明.
它不適用于受嚴格的 Content-Security-Policy (CSP) 保護的頁面,該 CSP 會阻止腳本執行,因此在為 Firefox 編寫擴展時,我們應該改用 wrappedJSObject
方法.
It won't work on pages protected by a strict Content-Security-Policy (CSP) that prevents script execution so when writing an extension for Firefox we should use wrappedJSObject
method instead.
這篇關于為什么這段代碼不起作用?我正在創建一個 Firefox 擴展,但代碼沒有運行.但是,如果我將代碼粘貼到控制臺中,它就可以工作的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!