navigator.clipboard未定义

时间:2018-08-12 03:16:11

标签: google-chrome clipboard

为什么以下代码段中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的更多信息,请参见here

Chrome版本:68.0.3440.106。

我确定这在某些时候可行,但现在不再可行。之所以令人困惑,是因为this table建议将剪贴板API在Chrome中实现(已经有一段时间了),但是this table的特定API方法表明不支持该API的方法? >

3 个答案:

答案 0 :(得分:12)

这需要一个安全的来源-HTTPS或localhost(或通过运行带有标志的Chrome禁用)。与ServiceWorker一样,此状态由导航器对象上属性的存在或不存在来指示。

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

这在规范中通过接口https://w3c.github.io/clipboard-apis/#dom-navigator-clipboard

带有[SecureContext]进行了说明。

您可以检查window.isSecureContext的状态,以了解是否是某功能不可用的原因。 Secure contexts | MDN

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

答案 1 :(得分:11)

您可以编写一个多合一的包装函数。

  • 如果在安全上下文 (https) 中:使用导航剪贴板 api
  • 如果不是:使用“视口外隐藏文本区域”技巧
// return a promise
function copyToClipboard(textToCopy) {
    // navigator clipboard api needs a secure context (https)
    if (navigator.clipboard && window.isSecureContext) {
        // navigator clipboard api method'
        return navigator.clipboard.writeText(textToCopy);
    } else {
        // text area method
        let textArea = document.createElement("textarea");
        textArea.value = textToCopy;
        // make the textarea out of viewport
        textArea.style.position = "fixed";
        textArea.style.left = "-999999px";
        textArea.style.top = "-999999px";
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();
        return new Promise((res, rej) => {
            // here the magic happens
            document.execCommand('copy') ? res() : rej();
            textArea.remove();
        });
    }
}

使用:

copyToClipboard("I'm going to the clipboard !")
    .then(() => console.log('text copied !'))
    .catch(() => console.log('error'));

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

答案 2 :(得分:3)

尝试一下:

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);
});