Chrome扩展开发问题:如何在页面加载时自动执行eval注入的JS代码
问题核心原因
chrome.storage.local.get是异步API,调用该方法后回调函数不会立刻执行,你在回调外部判断entries是否存在对应域名配置时,entries还停留在初始的{"test": "test"}状态,没有拿到存储里的真实数据,所以判断失效,eval不会执行window.onload赋值逻辑错误:你直接执行了eval(entries[domain])并把返回值赋值给window.onload,而不是将执行逻辑包装为函数赋值给事件回调,就算entries有值也不会在页面加载时触发
修复方案
直接修改content.js的loadChanges函数,把读取存储后的执行逻辑挪到异步回调内部,同时调整执行时机的判断即可:
//Content.js //Globals var entries = {"test": "test"}; //Entries dictionary "domain": "js code" var url = window.location.href; //Full URL of the tab var parts = url.split("/"); //URL split by '/' character var domain = parts[2] + ''; //Just the domain (global) loadChanges(); chrome.runtime.onMessage.addListener(listener); function listener (request, sender, sendResponse) { console.log("Manipulating data for: " + domain); if (request == "LOAD"){ if(entries.hasOwnProperty(domain)){ console.log("PE - Loaded Value: " + entries[domain].toString()); sendResponse(entries[domain]); } else { console.log("Nothing to load"); sendResponse(''); } } else { entries[domain] = request; console.log(entries[domain]); saveChanges(); eval(request); //This one DOES work } } //Load saved code (on startup) function loadChanges() { chrome.storage.local.get(['PE'], function (data){ console.log(data.PE); if (data.PE != null){ entries = data.PE; } // 拿到存储数据后再判断执行 if(entries.hasOwnProperty(domain)){ const customCode = entries[domain]; // 如果你需要等页面所有资源加载完再执行代码,保留下面的逻辑 if (document.readyState === 'complete') { eval(customCode); } else { window.addEventListener('load', () => eval(customCode)); } // 如果不需要等load事件,DOM加载完就执行,直接替换上面的逻辑为eval(customCode)即可 } }); } //Save changes to code (on button press) function saveChanges() { chrome.storage.local.set({PE: entries}, function(data){ console.log("Saved Value: " + entries[domain]) }); }
额外说明
原来写的错误window.onload赋值代码可以直接删掉,现在逻辑已经整合到loadChanges的异步回调里,会自动根据页面加载状态执行对应的自定义代码。
内容的提问来源于stack exchange,提问作者Scrub Nugget
相关产品推荐
相关产品推荐

