我正在使用Firefox权限API记录HERE
我遇到request
方法的问题,其中所有权限请求都会导致:
Error: permissions.request may only be called from a user input handler
你可以通过调试任何插件或扩展并在控制台中输入browser.permissions.request({origins: ["https://google.com/*"]})
来在firefox中生成它。
我发现很难知道权限请求必须始终在父堆栈跟踪中具有用户输入事件回调。我正在使用Vue.js,我的权限是由于用户交互,但我的用户交互与它们触发的事件分离。
user input handler
?有没有好的解决方法“
我想用一些代码示例添加Andrew的答案。
事实证明,promise链破坏了浏览器的概念,即用户输入处理程序触发和不触发的内容。以下面的代码为例:
document.getElementById('foo').addEventListener('click', event => {
browser.permissions.request({origins: ["https://google.com/*"]})
})
此代码按预期工作。我最初认为是Vue.js独特的事件处理框架正在吃我的“浏览器事件”,比如当你做<div @click="somefunc"></div>
时。只要您将权限请求放在somefunc
中,这实际上就可以正常工作。
现在它变得有趣。如果您将权限请求替换为解析然后执行权限请求的承诺,VIOLA!
Promise.resolve('foobar').then(foobar => {
browser.permissions.request({origins: ["https://google.com/*"]})
})
结果是:
Error: permissions.request may only be called from a user input handler
为什么会这样?
我猜它会与堆栈跟踪有关。如果权限请求发生在promise链中,Firefox无法检测到权限来自具有root用户输入事件的堆栈。
我认为这是一个非常令人震惊的设计选择。我的应用程序很大(> 4K LoC)并且为了保持简单,我依靠承诺链来保持意大利面。这削弱了我编写干净代码的能力,因此,我已经从请求optional_permissions
转移,然后仅在需要时才提示用户权限,以便在安装时过度宽松。
GG,Firefox。
什么算作用户输入处理程序?
对应于用户输入的DOM事件处理程序(例如,target.addEventHandler("click", ...)
或对应于用户输入的WebExtension事件侦听器(例如,browser.browserAction.onClicked.addListener(...)
)
它为什么这样工作?
部分用于基本的用户体验(如果用户没有直接与扩展程序交互并且扩展程序的提示突然提示,它可能很容易混淆他们),而且还要避免在精心挑选的时刻提出提示的点击劫持攻击用户可能期待一些不相关的提示。
有一个很好的解决方案吗?
我认为只是组织你的代码,以便你从用户输入处理程序请求权限可能是你最好的选择。