复制内容显示navigator.clipboard undefined的问题与解决

好久没写博客,太忙了。今天因为遇到复制文本的bug,在这里记录一下~

分析问题

起因是测试提了个不管:点击单号复制小图标,会报脚本错误。
报错信息显示的就是 TypeError: Cannot read properties of undefined (reading ‘writeText’)
但是我自己在本地测试时,是没有问题的,在demo网站也没有问题。

在我要了测试的ip地址去测试,发现确实是会报错。
在查看相关代码发现问题在于,navigator对象下是否有clipboard对象。
在这里插入图片描述

在翻阅MDN文档后,发现问题所在。这个Navigator的clipboard属性是有限制的,必须是在支持的浏览器和安全上下文中可用。那么像我们的本地localhost,和我刚才的demo网站是用https的这些都属于安全上下文,所以测试并没有问题。在测试的机器里,因为是自己的ip域,并不是https。这个功能就会失效,所以就会报错undefined了
在这里插入图片描述
我们可以通过window.isSecureContext来判断是否是安全上下文。
在这里插入图片描述

在这里插入图片描述

如何解决

1.代码兼容非安全域的写法。

在安全域下使用 navigator.clipboard 提升效率,非安全域退回到 document.execCommand(‘copy’); 保证功能一直可用。

 const handleCopy = (val) => {
    if (window.isSecureContext && navigator.clipboard) {
      navigator.clipboard
        .writeText(val)
        .then(() => {
          ElMessage({
            showClose: false,
            message: t('audit_center.other_source.success_copy'),
            type: 'success',
          });
        })
        .catch((err) => {
          ElMessage({
            showClose: false,
            message: `${t('audit_center.other_source.fail_copy')}${err}`,
            type: 'error',
          });
        });
    } else {
      const copyElem = document.createElement('textarea');
      let styles = copyElem.style;
      styles.position = 'fixed';
      styles.zIndex = '0';
      styles.left = '-500px';
      styles.top = '-500px';
      copyElem.value = val;
      document.body.appendChild(copyElem);
      copyElem.focus();
      copyElem.select();
      let result = false;
      result = document.execCommand('copy');
      if (result) {
        ElMessage({
          showClose: false,
          message: t('audit_center.other_source.success_copy'),
          type: 'success',
        });
        copyElem.remove();
      } else {
        ElMessage({
          showClose: false,
          message: `${t('audit_center.other_source.fail_copy')}`,
          type: 'error',
        });
      }
    }
  };

  1. 引用第三方库

社区上有很多开源的复制剪切的jS库可以使用,第三方库考虑的比较全面,兼容问题都会处理好。
vue3-clipboard
xe-clipboard

import { toClipboard } from '@soerenmartius/vue3-clipboard';

const handleCopy = (val) => {
    toClipboard(val)
      .then((res) => {
        ElMessage({
          showClose: false,
          message: t('audit_center.other_source.success_copy'),
          type: 'success',
        });
      })
      .catch((err) => {
        ElMessage({
          showClose: false,
          message: `${t('audit_center.other_source.fail_copy')}${err}`,
          type: 'error',
        });
      });
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值