navigator.clipboard是undefined

回答 7 浏览 14万 2018-08-12

为什么在下面的片段中,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的更多信息,可以在这里找到。

浏览器版本:68.0.3440.106。

我确信这在某些时候是可行的,但现在已经不行了。这很令人困惑,因为此表表明Chrome中实现了剪贴板API(已经有一段时间了),但此表的具体API方法表明,该API的所有方法都不被支持?

drmrbrewer 提问于2018-08-12
该页面是否从安全的源头提供?Josh Lee 2018-08-13
Aaaaah @JoshLee.... 这就不同了......原点是安全的(可通过https访问),但由于某些原因,我是通过http访问的......当我通过https访问时,clipboard对象是可用的!这解释了为什么我确信它之前一直在工作。也许我应该把所有的http转为https。谢谢......如果你提交一个答案,我将把它标记为正确。drmrbrewer 2018-08-13
我也有同样的问题,但这里给出的解决方案并不奏效。直到我发现,文本区或文本字段可能没有被禁用!!!Harm 2020-03-02
7 个回答
#1楼 已采纳
得票数 229

这需要一个安全的起源--HTTPS或localhost(或者通过运行Chrome浏览器的标志来禁用)。就像ServiceWorker一样,这种状态通过导航器对象上的属性的存在或不存在来表示。

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。

Josh Lee 提问于2018-08-13
Josh Lee 修改于2018-12-21
BTW,禁用TEMPORARILY https检查的标志是,例如: --unsafely-treat-insecure-origin-as-secure=myexamplesite.comRikiRiocma 2020-02-03
chrome://flags中,启用Insecure origins treated as secure,并给它一个你想要的原点。Rokit 2020-12-07
无论我用什么方法,都无法运行Chrome的无头程序。danronmoon 2022-05-16
#2楼
得票数 108

你可以写一个全能型的包装函数。

  • 如果在安全环境下(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/这样的复制中尝试。

Simon Dehaut 提问于2021-02-01
Lucas Mendonca 修改于2023-03-13
酷,有点简明:textArea.style.position = "absolute"; textArea.style.opacity = 0;,我认为焦点调用是不必要的NanoNova 2021-03-13
由于document.exeCommand已经被弃用,任何其他的方式都可以实现。Colasanto 2021-09-13
谢谢你对https上下文的解释;这在其他例子中是一个神秘的阻挡因素。MarsAndBack 2022-01-20
不幸的是,我一直得到DOMException: Document is not focused. :( 从chrome的代码片段中调用它。Kamajabu 2022-03-12
#3楼
得票数 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);
});
Juliano Costa 提问于2020-02-19
kohane15 修改于2021-07-16
document.execCommand('copy');被取消了。key 2022-04-07
#4楼
得票数 5

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

Chrome > settings > privacy and Security > site settings > View permissions and data stored across sites 然后点击你的本地主机 URL,它会在页面上显示并检查剪贴板的权限

Ramkrishna Bhatt 提问于2022-04-21
#5楼
得票数 5

当HTTPS还不能使用时,用document.execCommand('copy')的解决方案不能工作,这是一个复制工具提示的最小解决方案。 但它需要用户用手选择并复制显示在提示中的内容。

function copyToClipboard(text) {
    if(navigator.clipboard) {
        navigator.clipboard.writeText(text);
    }
    else{
        alert(text);
    }
}
Laurent Lyaudet 提问于2021-10-14
Laurent Lyaudet 修改于2022-07-20
我使用的是chrome v105,无法选择警报文本:()leverglowh 2022-09-13
你好,我刚刚在Ubuntu 22.04上测试了它,它工作了:版本105.0.5195.102。看起来很奇怪,Chrome会删除这个功能。Laurent Lyaudet 2022-09-13
也许你在智能手机上使用Chrome浏览器,在那里选择文本可能会很麻烦?Laurent Lyaudet 2022-09-13
这可能与这个错误有关 support.google.com/chrome/thread/9959602/…我的文字其实很长,我用了一个提示语代替:)leverglowh 2022-09-14
#6楼
得票数 2

这个解决方案目前是可行的(它包括跨浏览器支持、错误处理+清理)。

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

jazkat 提问于2021-10-11
似乎不再起作用了key 2022-04-07
很漂亮,它尝试了3种自动方法,如果失败了,它就会显示一个手动警报。它可以根据你的需要进行改进,但总的来说,它是我迄今为止看到的最好的解决方案(搜索了一个小时)。Filip Happy 2022-04-11
仅有链接的答案在SO上不被认为是有价值的。如果这个答案是正确的,这个问题应该被标记为重复的。isherwood 2022-06-24
#7楼
得票数 -2

你可以使用:

改为:

navigator.clipboard.writeText("内容")

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

Lutfi Fahmani 提问于2022-09-23
你建议的改变不是一个改变。这两行代码是相同的。它们做同样的事情。这只是用不同的方式来指示浏览器做同样的事情。0xC0DEGURU 2023-01-16
但就我而言,这是可行的Lutfi Fahmani 2023-04-15