esq*_*qew 30 javascript google-chrome google-chrome-extension
有没有办法从谷歌Chrome内容脚本中检索页面的javascript变量?
Lir*_*mer 20
我创建了一个小帮手方法,玩得开心:)
检索窗口的变量"lannister","always","pays","his","debts",执行以下命令:
var windowVariables = retrieveWindowVariables(["lannister", "always", "pays", "his", "debts"]);
console.log(windowVariables.lannister);
console.log(windowVariables.always);
Run Code Online (Sandbox Code Playgroud)
我的代码:
function retrieveWindowVariables(variables) {
var ret = {};
var scriptContent = "";
for (var i = 0; i < variables.length; i++) {
var currVariable = variables[i];
scriptContent += "if (typeof " + currVariable + " !== 'undefined') $('body').attr('tmp_" + currVariable + "', " + currVariable + ");\n"
}
var script = document.createElement('script');
script.id = 'tmpScript';
script.appendChild(document.createTextNode(scriptContent));
(document.body || document.head || document.documentElement).appendChild(script);
for (var i = 0; i < variables.length; i++) {
var currVariable = variables[i];
ret[currVariable] = $("body").attr("tmp_" + currVariable);
$("body").removeAttr("tmp_" + currVariable);
}
$("#tmpScript").remove();
return ret;
}
Run Code Online (Sandbox Code Playgroud)
请注意我使用jQuery ..您可以轻松地使用本机js "removeAttribute"和"removeChild".
小智 14
使用Liran的解决方案,我正在添加一些修复Objects,这是正确的解决方案:
function retrieveWindowVariables(variables) {
var ret = {};
var scriptContent = "";
for (var i = 0; i < variables.length; i++) {
var currVariable = variables[i];
scriptContent += "if (typeof " + currVariable + " !== 'undefined') $('body').attr('tmp_" + currVariable + "', JSON.stringify(" + currVariable + "));\n"
}
var script = document.createElement('script');
script.id = 'tmpScript';
script.appendChild(document.createTextNode(scriptContent));
(document.body || document.head || document.documentElement).appendChild(script);
for (var i = 0; i < variables.length; i++) {
var currVariable = variables[i];
ret[currVariable] = $.parseJSON($("body").attr("tmp_" + currVariable));
$("body").removeAttr("tmp_" + currVariable);
}
$("#tmpScript").remove();
return ret;
}
Run Code Online (Sandbox Code Playgroud)
Chrome 的文档为您提供了一个很好的起点:https : //developer.chrome.com/extensions/content_scripts#host-page-communication
此方法允许您将全局页面变量提取到内容脚本中。它还使用一个想法来只接受您在握手时识别的传入消息。你也可以只Math.random()用于握手,但我玩得很开心。
propagateVariable并将当前的 handShake 和目标变量名称传递到字符串中以进行保存,因为函数将无法访问我们的内容脚本范围。const globalToExtract = 'someVariableName';
const array = new Uint32Array(5);
const handShake = window.crypto.getRandomValues(array).toString();
function propagateVariable(handShake, variableName) {
const message = { handShake };
message[variableName] = window[variableName];
window.postMessage(message, "*");
}
(function injectPropagator() {
const script = `( ${propagateVariable.toString()} )('${handShake}', '${globalToExtract}');`
const scriptTag = document.createElement('script');
const scriptBody = document.createTextNode(script);
scriptTag.id = 'chromeExtensionDataPropagator';
scriptTag.appendChild(scriptBody);
document.body.append(scriptTag);
})();
window.addEventListener("message", function({data}) {
console.log("INCOMINGGGG!", data);
// We only accept messages from ourselves
if (data.handShake != handShake) return;
console.log("Content script received: ", data);
}, false);Run Code Online (Sandbox Code Playgroud)
function extractGlobal(variableName) {
const array = new Uint32Array(5);
const handShake = window.crypto.getRandomValues(array).toString();
function propagateVariable(handShake, variableName) {
const message = { handShake };
message[variableName] = window[variableName];
window.postMessage(message, "*");
}
(function injectPropagator() {
const script = `( ${propagateVariable.toString()} )('${handShake}', '${variableName}');`
const scriptTag = document.createElement('script');
const scriptBody = document.createTextNode(script);
scriptTag.id = 'chromeExtensionDataPropagator';
scriptTag.appendChild(scriptBody);
document.body.append(scriptTag);
})();
return new Promise(resolve => {
window.addEventListener("message", function({data}) {
// We only accept messages from ourselves
if (data.handShake != handShake) return;
resolve(data);
}, false);
});
}
extractGlobal('someVariableName').then(data => {
// Do Work Here
});Run Code Online (Sandbox Code Playgroud)
如果使用 es 模块,我建议将类放入自己的文件中并将其导出为默认值。然后它就变成了:
ExtractPageVariable('someGlobalPageVariable').data.then(pageVar => {
// Do work here
});
Run Code Online (Sandbox Code Playgroud)
ExtractPageVariable('someGlobalPageVariable').data.then(pageVar => {
// Do work here
});
Run Code Online (Sandbox Code Playgroud)
正如其他答案中部分解释的那样,页面中的 JS 变量与 Chrome 扩展内容脚本隔离。通常,没有办法访问它们。
但是,如果您在页面中注入 JavaScript 标记,您将可以访问那里定义的任何变量。
我使用实用程序函数将脚本注入页面中:
/**
* inject - Inject some javascript in order to expose JS variables to our content JavaScript
* @param {string} source - the JS source code to execute
* Example: inject('(' + myFunction.toString() + ')()');
*/
function inject(source) {
const j = document.createElement('script'),
f = document.getElementsByTagName('script')[0];
j.textContent = source;
f.parentNode.insertBefore(j, f);
f.parentNode.removeChild(j);
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
function getJSvar(whichVar) {
document.body.setAttribute('data-'+whichVar,whichVar);
}
inject('(' + getJSvar.toString() + ')("somePageVariable")');
var pageVar = document.body.getAttribute('data-somePageVariable');
Run Code Online (Sandbox Code Playgroud)
请注意,如果变量是复杂的数据类型(对象、数组...),则需要将值作为 JSON 字符串存储在 getJSvar() 中,并通过 JSON.parse 将其返回到内容脚本中。
| 归档时间: |
|
| 查看次数: |
25305 次 |
| 最近记录: |