使用Firefox中<select> onchange处理程序的Permissions API请求权限

Sei*_*Sys 5 javascript permissions firefox firefox-addon firefox-addon-webextensions

我目前正在开发一个Firefox附加组件,它使用权限API根据a的值动态请求特定来源的权限 <select>,因为用户更改了值,而没有单独的提交按钮.当我打电话时browser.permissions.request,承诺会立即被拒绝并出现错误:

permissions.request只能从用户输入处理程序调用

相关的HTML和JS代码如下.我想避免使用单独的保存按钮,但我不知道如何实现这一点.是否可能,如果可能,怎么样?

<div id="domain-settings">
    Choose your preferred domain:
    <select>
        <option>example.com</option>
        <option>one.example.com</option>
        <option>other.example.com</option>
    </select>
</form>
Run Code Online (Sandbox Code Playgroud)
const settings = { domain: 'example.com' };
const $select = $('#domain-settings').find('select');
$select.on('change',function(e){
    e.stopPropagation();
    const oldValue = settings.domain;
    const perm = { origins: [ `https://${$select.val()}/` ] };
    browser.permissions.contains(perm)
        .then(result => {
            if (result)
                someFunction();
            else browser.permissions.request(perm)
                .then(granted => {
                    if (granted)
                        someFunction();
                    else $select.val(oldValue);
                });
        })
})();
Run Code Online (Sandbox Code Playgroud)

Sei*_*Sys 1

几天前,当我在代码库中重新发现这个错误时,我以某种方式偶然发现了这个问题,甚至不记得我在这里发布过它。这个问题有一个几乎相同的答案,但就我而言,问题具体在于我在尝试请求之前检查了许可,事实证明,这是完全没有必要的。

同样的解释也适用于此。Firefox 无法识别来自用户输入的处理程序,因为它被链接在一个承诺调用中,这会破坏它可以用来验证这一点的调用堆栈。如果permissions.request在任何承诺之后链接调用,它将不会通过此验证。

我的解决方案:放弃permissions.contains支票。现在一切都按预期进行。

const settings = { domain: 'example.com' };
const $select = $('#domain-settings').find('select');
$select.on('change',function(e){
    e.stopPropagation();
    const oldValue = settings.domain;
    const perm = { origins: [ `https://${$select.val()}/` ] };
    browser.permissions.request(perm)
        .then(granted => {
            if (granted)
                someFunction();
            else $select.val(oldValue);
        });
})();
Run Code Online (Sandbox Code Playgroud)