navigator.clipboard 未定义

navigator.clipboard is undefined

为什么下面的代码段中 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 suggests that the Clipboard API is implemented in Chrome (has been for some time), but this table of specific API methods suggests that none of the methods of the API is supported??

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

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

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

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

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

试试这个:

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

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

  • 如果在安全上下文中 (https):使用导航器剪贴板 api
  • 如果没有:使用 'out of viewport hidden text area' 技巧
// 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 中尝试

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

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

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

在本地主机中,剪贴板被 chrome 浏览器阻止。您可以通过以下路径检查这一点

Chrome > 设置 > 隐私和安全 > 站点设置 > 查看跨站点存储的权限和数据,然后单击您的本地主机 URL,这将在页面上显示并检查剪贴板的权限