Firefox插件覆写window.ApplePaySession失效,如何检测Apple Pay支持?
问题根源:内容脚本的隔离执行环境
哦,这个坑我之前也踩过!问题出在Firefox(以及Chrome等现代浏览器)的内容脚本运行在隔离的执行环境里——你在内容脚本中修改的window对象,和页面本身的JavaScript代码所访问的window根本不是同一个实例。页面的原生JS完全看不到你在内容脚本里做的任何修改,所以你的ApplePaySession模拟等于白写了。
浏览器设计这个隔离机制是为了安全:内容脚本不会污染页面的全局环境,同时也能避免页面的恶意代码影响扩展。但这就导致你直接在内容脚本里修改window的操作,对页面原生上下文完全无效。
解决方案:将代码注入到页面主上下文
要让页面的JS能访问到你模拟的ApplePaySession,你需要把代码注入到页面的主执行上下文中。最直接的方式是创建一个<script>元素,把你的模拟代码写进去,再插入到页面的DOM里,这样代码就会在页面原生的全局环境中执行。
修改你的applepay.js为如下代码:
// 创建script标签,承载要注入到页面的代码 const injectScript = document.createElement('script'); injectScript.textContent = ` window.ApplePaySession = { canMakePayments: function () { console.log('canMakePayments'); return Promise.resolve(true); }, canMakePaymentsWithActiveCard: function () { console.log('canMakePaymentsWithActiveCard'); // 注意:你之前这里漏写了return,会导致返回undefined而非Promise return Promise.resolve(true); }, }; `; // 将script标签插入到页面头部,触发代码执行 document.head.appendChild(injectScript); // 执行完成后可以移除标签,不影响功能 injectScript.remove();
额外细节提醒
- 你之前的
canMakePaymentsWithActiveCard函数遗漏了return语句,这会导致它返回undefined而不是预期的Promise,我在修改后的代码里已经补上了。 - 这种注入方式在Manifest V2中无需额外权限,因为只是常规的DOM操作;如果未来升级到Manifest V3,需要使用
scriptingAPI来注入代码,但你的当前场景用Manifest V2的写法完全没问题。
内容的提问来源于stack exchange,提问作者ceejayoz
相关产品推荐
相关产品推荐

