如何修改Chrome扩展中的injectScript函数以注入Brython代码?
如何修改injectScript函数以注入Brython代码?
我明白你现在遇到的问题:用现有的injectScript能正常加载普通JS,但加载Brython代码时完全没反应,既不报错也不执行。这其实是因为Brython的执行逻辑和普通JS不一样,咱们一步步来解决:
问题根源
- Brython不会自动处理动态添加的Python脚本:Brython默认只会在页面初始加载时扫描一次带有
text/python类型的脚本标签,之后动态添加的标签不会被自动解析执行。 - 版本不兼容风险:你加载的
brython.min.js是3.8.9版本,但brython_stdlib.min.js是3.9.5版本,版本不一致可能导致隐藏问题。 - 缺少Brython初始化步骤:加载Brython核心库后,需要主动调用
brython()完成初始化,否则后续的Python代码无法被解析。
解决方案一:修改现有injectScript支持Brython脚本
我们可以给原函数加个参数,标记是否为Python脚本,加载完成后主动调用Brython的API执行它:
function injectScript(src, isPython = false){ return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = src; // 为Python脚本设置正确的type属性 script.setAttribute('type', isPython ? 'text/python' : 'text/javascript'); script.addEventListener('load', async () => { if (isPython) { try { // 主动获取脚本内容并通过Brython API执行 const code = await (await fetch(src)).text(); brython_run_script(code); resolve(); } catch (err) { reject(err); } } else { resolve(); } }); script.addEventListener('error', e => reject(e.error)); document.head.appendChild(script); }); }
然后调整调用逻辑,确保初始化Brython并使用相同版本的核心库和stdlib:
// 统一使用3.9.5版本,避免兼容问题 injectScript("https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.5/brython.min.js") .then(() => { console.log('Brython核心库加载完成!'); // 初始化Brython,开启debug模式方便排查问题 brython({debug: 1}); return injectScript("https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.5/brython_stdlib.min.js"); }) .then(() => { console.log('Brython标准库加载完成!'); // 注入Python脚本,标记isPython为true return injectScript(chrome.runtime.getURL("/python.js"), true); }) .then(() => { console.log("Python代码执行完成!") }) .catch(error => { console.error('加载/执行出错:', error); });
解决方案二:专门编写injectPython函数(更简洁可靠)
如果不需要复用原函数,直接写一个专门加载执行Python代码的函数会更清晰:
function injectPython(src){ return fetch(src) .then(res => { if (!res.ok) throw new Error(`加载脚本失败: ${res.status}`); return res.text(); }) .then(code => { // 直接调用Brython的API执行代码 brython_run_script(code); return Promise.resolve(); }) .catch(err => Promise.reject(err)); }
调用方式和上面类似,确保先初始化Brython:
injectScript("https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.5/brython.min.js") .then(() => { console.log('Brython核心库加载完成!'); brython({debug: 1}); return injectScript("https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.5/brython_stdlib.min.js"); }) .then(() => { console.log('Brython标准库加载完成!'); return injectPython(chrome.runtime.getURL("/python.js")); }) .then(() => { console.log("Python代码执行完成!") }) .catch(error => { console.error('加载/执行出错:', error); });
额外注意事项
- 确保页面存在目标元素:你的Python代码里绑定了
document['mybutton'],要确保页面上确实存在id为mybutton的按钮,否则会报错。可以给Python代码加个容错处理:from browser import document, alert import traceback def hello(): alert("hello world") try: if 'mybutton' in document: document['mybutton'].bind('click', hello) else: print("未找到id为mybutton的元素") except Exception as e: traceback.print_exc() - debug模式排查:初始化Brython时开启
debug:1,可以在控制台看到详细的执行日志,方便定位问题。
内容的提问来源于stack exchange,提问作者w1nter
相关产品推荐
相关产品推荐

