为什么将授权从 none 更改为 GM_xmlhttpRequest 会破坏我的代码?
Why does changing grant from none to GM_xmlhttpRequest break my code?
简而言之,我不想提醒 URL 和响应正文,而是将其发送到我的应用程序。此代码有效,但我不能使用 GM_xmlhttpRequest 除非我授予它。
不改变任何其他代码神奇地中断。我不确定更改了什么以及如何修复它。我以为我可以在我的应用程序中使用 console.log
和 copy/paste 数据,但是 Facebook 禁用了 console.log。
我考虑过执行 xmlhttpRequest,但不知为何也被阻止了。我通过在控制台中执行代码进行了测试。除了 Facebook 域外,这 3 行似乎在任何地方都有效。我相信它与CORS有关。
// ==UserScript==
// @name FBTest
// @namespace test
// @include https://*.facebook.com/*
// @version 1
// @grant none
// ==/UserScript==
//change none to GM_xmlhttpRequest
(function() {
var proxied = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function(method, url) {
alert(url);
return proxied.apply(this, [].slice.call(arguments));
};
})();
当您授予 GM_xmlhttpRequest、it switches on the sandbox 时 -- 这意味着您无法访问 window.XMLHttpRequest
,因为它现在处于不同的上下文中。
要解决此问题,请使用 script injection to intercept the AJAX. And, use either messaging 或自定义事件来访问用户脚本上下文中的数据。
这是一个使用自定义事件的示例脚本(不太容易受到第 3 方攻击):
// ==UserScript==
// @name _Intercept AJAX with grant/sandbox on
// @match https://*.facebook.com/*
// @grant GM_xmlhttpRequest
// ==/UserScript==
function xmlOpenIntercept () {
var proxied = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, newUrl) {
var cEvnt = new CustomEvent ('newAjaxStart', {'detail': newUrl} );
document.body.dispatchEvent (cEvnt);
return proxied.apply (this, [].slice.call (arguments) );
};
}
addJS_Node (null, null, xmlOpenIntercept); //-- Injects code
//--- This code listens for the right kind of message.
document.body.addEventListener ("newAjaxStart", receiveAjaxMessage);
function receiveAjaxMessage (zEvent) {
console.log ("Intercepted AJAX to: ", zEvent.detail);
}
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D = document;
var scriptNode = D.createElement ('script');
if (runOnLoad) scriptNode.addEventListener ("load", runOnLoad);
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
简而言之,我不想提醒 URL 和响应正文,而是将其发送到我的应用程序。此代码有效,但我不能使用 GM_xmlhttpRequest 除非我授予它。
不改变任何其他代码神奇地中断。我不确定更改了什么以及如何修复它。我以为我可以在我的应用程序中使用 console.log
和 copy/paste 数据,但是 Facebook 禁用了 console.log。
我考虑过执行 xmlhttpRequest,但不知为何也被阻止了。我通过在控制台中执行代码进行了测试。除了 Facebook 域外,这 3 行似乎在任何地方都有效。我相信它与CORS有关。
// ==UserScript==
// @name FBTest
// @namespace test
// @include https://*.facebook.com/*
// @version 1
// @grant none
// ==/UserScript==
//change none to GM_xmlhttpRequest
(function() {
var proxied = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function(method, url) {
alert(url);
return proxied.apply(this, [].slice.call(arguments));
};
})();
当您授予 GM_xmlhttpRequest、it switches on the sandbox 时 -- 这意味着您无法访问 window.XMLHttpRequest
,因为它现在处于不同的上下文中。
要解决此问题,请使用 script injection to intercept the AJAX. And, use either messaging 或自定义事件来访问用户脚本上下文中的数据。
这是一个使用自定义事件的示例脚本(不太容易受到第 3 方攻击):
// ==UserScript==
// @name _Intercept AJAX with grant/sandbox on
// @match https://*.facebook.com/*
// @grant GM_xmlhttpRequest
// ==/UserScript==
function xmlOpenIntercept () {
var proxied = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, newUrl) {
var cEvnt = new CustomEvent ('newAjaxStart', {'detail': newUrl} );
document.body.dispatchEvent (cEvnt);
return proxied.apply (this, [].slice.call (arguments) );
};
}
addJS_Node (null, null, xmlOpenIntercept); //-- Injects code
//--- This code listens for the right kind of message.
document.body.addEventListener ("newAjaxStart", receiveAjaxMessage);
function receiveAjaxMessage (zEvent) {
console.log ("Intercepted AJAX to: ", zEvent.detail);
}
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D = document;
var scriptNode = D.createElement ('script');
if (runOnLoad) scriptNode.addEventListener ("load", runOnLoad);
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}