navigator.clipboard 未定义

问题描述 投票:0回答:7

为什么

navigator.clipboard
在下面的片段中总是
undefined

var clipboard = navigator.clipboard;
if (clipboard == undefined) {
    console.log('clipboard is undefined');
} else {
    clipboard.writeText('stuff to write').then(function() {
        console.log('Copied to clipboard successfully!');
    }, function() {
        console.error('Unable to write to clipboard. :-(');
    });
}

有关剪贴板 API 的更多信息,请参见此处.

Chrome 版本:68.0.3440.106.

我确定这在某些时候是有效的,但现在不再是了。很迷惑,因为这张表暗示在Chrome中实现了Clipboard API(已经有一段时间了),但是这张表具体的API方法却表明不支持API的任何方法??

google-chrome clipboard
7个回答
224
投票

这需要一个安全来源——HTTPS 或本地主机(或通过运行带有标志的 Chrome 来禁用)。就像 ServiceWorker 一样,此状态由 navigator 对象上的属性存在与否指示。

https://developers.google.com/web/updates/2018/03/clipboardapi

这在接口上带有 [SecureContext] 的规范中有所说明:https://w3c.github.io/clipboard-apis/#dom-navigator-clipboard

您可以检查

window.isSecureContext
的状态以了解这是否是某项功能不可用的原因。 安全上下文 | MDN

是的,您应该设置 HSTS 以确保 HTTP 重定向到 HTTPS。


103
投票

您可以编写一个一体化包装函数。

  • 如果在安全上下文中 (https):使用导航器剪贴板 api
  • 如果不是:使用“视口外隐藏文本区域”技巧
async function copyToClipboard(textToCopy) {
    // Navigator clipboard api needs a secure context (https)
    if (navigator.clipboard && window.isSecureContext) {
        await navigator.clipboard.writeText(textToCopy);
    } else {
        // Use the 'out of viewport hidden text area' trick
        const textArea = document.createElement("textarea");
        textArea.value = textToCopy;
            
        // Move textarea out of the viewport so it's not visible
        textArea.style.position = "absolute";
        textArea.style.left = "-999999px";
            
        document.body.prepend(textArea);
        textArea.select();

        try {
            document.execCommand('copy');
        } catch (error) {
            console.error(error);
        } finally {
            textArea.remove();
        }
    });
}

用法:

try {
    await copyToClipboard("I'm going to the clipboard !");
    console.log('Text copied to the clipboard!');
} catch(error) {
    console.error(error);
}

ps:不要在像 jsfiddle/copeden/...这样的 repl 中尝试它


14
投票

试试这个:

if (typeof (navigator.clipboard) == 'undefined') {
    console.log('navigator.clipboard');
    var textArea = document.createElement("textarea");
    textArea.value = linkToGo;
    textArea.style.position = "fixed";  //avoid scrolling to bottom
    document.body.appendChild(textArea);
    textArea.focus();
    textArea.select();

    try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        toastr.info(msg);
    } catch (err) {
        toastr.warning('Was not possible to copy te text: ', err);
    }

    document.body.removeChild(textArea)
    return;
}
navigator.clipboard.writeText(linkToGo).then(function () {
    toastr.info(`successful!`);
}, function (err) {
    toastr.warning('unsuccessful!', err);
});

5
投票

在localhost中,剪贴板被chrome浏览器屏蔽了。您可以通过以下路径进行检查

Chrome > settings > privacy and Security > site settings > View permissions and data stored across sites then click on your localhost URL which will mention on the page and check the permission of the clipboard


5
投票

当 HTTPS 尚不可用且 document.execCommand('copy') 的解决方案不起作用时,复制工具提示的最小解决方案。 但它需要用户手动选择和复制警报中显示的内容。

function copyToClipboard(text) {
    if(navigator.clipboard) {
        navigator.clipboard.writeText(text);
    }
    else{
        alert(text);
    }
}

2
投票

此解决方案目前有效(包括跨浏览器支持、错误处理 + 清理)。

https://stackoverflow.com/a/33928558/318380


-2
投票

你可以使用:

改变:

navigator.clipboard.writeText("内容")

到: navigator['clipboard'].writeText("Content") 代替。

© www.soinside.com 2019 - 2024. All rights reserved.