navigator.clipboard的兼容性问题

解决navigator.clipboard的兼容性问题

  1. 问题描述:在实现快捷复制的时候出现的一个问题,使用navigator.clipboard实现复制的时候,在本地测试没有问题,但是上线之后复制不能正常使用。
  2. 问题分析:这个问题可能是由于浏览器安全策略导致的。在本地开发环境中,navigator.clipboard API 可以正常工作,但在生产环境中,由于安全限制,只有在以下条件下才能使用剪贴板API:1. 网站必须使用HTTPS协议;2. 网页必须处于活动标签页;3. 用户必须已经授予剪贴板权限。建议检查生产环境是否满足这些条件,特别是HTTPS协议的支持情况。如果确实是HTTPS环境,那么可能是浏览器没有正确授予剪贴板权限,或者在某些浏览器中clipboard API的支持存在兼容性问题。但是我使用同一个浏览器,排除浏览器兼容,发现是上线之后的协议是http协议。
  3. 解决方案:由于环境使用的是HTTP协议,而navigator.clipboard API在非HTTPS环境下会受到安全策略限制。有以下解决方案:1. 将网站升级到HTTPS协议(推荐);2. 使用传统的document.execCommand(‘copy’)方法作为降级方案;3. 如果必须使用HTTP,可以考虑使用第三方复制库如clipboard.js作为替代方案。因为使用什么协议不是我决定的,所以最后用传统的document.execCommand(‘copy’)做降级处理。
  4. 代码:
  • 降级之前代码
<template>
  <div class="text-container" @mouseenter="showButton = true" @mouseleave="showButton = false">
    <!-- 复制按钮,仅在鼠标悬停时显示 -->
    <el-tooltip placement="top" content="复制">
    <el-icon v-if="showButton" class="copy-button" @click="handleCopy"><CopyDocument /></el-icon>
   </el-tooltip>
    <!-- 显示的内容 -->
    <div class="content">
      <slot></slot>
    </div>
  </div>
</template>

<script setup>
import { ref } from "vue";
import { CopyDocument } from "@element-plus/icons-vue";
import { message } from "@/utils/message";

// 定义 Props
const props = defineProps({
  text: {
    type: String,
    required: true // 必填项,表示需要复制的文字
  }
});

// 控制复制按钮的显示状态
const showButton = ref(false);

// 复制文本到剪贴板
const handleCopy = () => {
  navigator.clipboard
    .writeText(props.text)
    .then(() => {
      message("复制成功", { type: "success" });
    })
    .catch(err => {
      console.error("复制失败:", err);
      message("复制失败", { type: "error" });
    });
};
</script>

<style lang="scss">
/* 基本样式 */
.text-container {
  position: relative; /* 父容器设置为相对定位 */
  display: block;
  padding: 0 10px;
  min-height: 24px; /* 确保容器有足够的高度 */
}

/* 内容区域 */
.content {
  padding-right: 30px; /* 为图标预留空间 */
  word-break: break-word; /* 允许文字换行 */
}

/* 复制按钮样式 */
.copy-button {
  position: absolute;
  top: 50%;
  right: 10px; /* 固定在最右侧并留出一些间距 */
  transform: translateY(-50%); /* 垂直居中 */
  color: #409eff;
  cursor: pointer;
  font-size: 16px;
  transition: all 0.3s;

  &:hover {
    color: #66b1ff;
  }
}

/* 使用伪类创建背景区域 */
.copy-button::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 32px; /* 背景宽度 */
  height: 32px; /* 背景高度 */
  background-color: rgba(0, 0, 0, .03); /* 背景颜色和透明度 */
  border-radius: 6px; /* 圆角效果 */
  z-index: -1; /* 确保背景区域在图标后面 */
  opacity: 0; /* 默认隐藏 */
  transition: opacity 0.3s; /* 平滑过渡效果 */
}

/* 悬停时显示背景区域 */
.copy-button:hover::after {
  opacity: 1; /* 显示背景 */
}
</style>

  • 优雅降级之后
<template>
  <div class="text-container" @mouseenter="showButton = true" @mouseleave="showButton = false">
    <!-- 复制按钮,仅在鼠标悬停时显示 -->
    <el-tooltip placement="top" content="复制">
    <el-icon v-if="showButton" class="copy-button" @click="handleCopy"><CopyDocument /></el-icon>
   </el-tooltip>
    <!-- 显示的内容 -->
    <div class="content">
      <slot></slot>
    </div>
  </div>
</template>

<script setup>
import { ref } from "vue";
import { CopyDocument } from "@element-plus/icons-vue";
import { message } from "@/utils/message";

// 定义 Props
const props = defineProps({
  text: {
    type: String,
    required: true // 必填项,表示需要复制的文字
  }
});

// 控制复制按钮的显示状态
const showButton = ref(false);

// 复制文本到剪贴板
const handleCopy = async () => {
  try {
    // 优先使用 navigator.clipboard API
    if (navigator.clipboard && window.isSecureContext) {
      await navigator.clipboard.writeText(props.text);
      message("复制成功", { type: "success" });
      return;
    }

    // 降级使用 document.execCommand
    const textArea = document.createElement('textarea');
    textArea.value = props.text;
    document.body.appendChild(textArea);
    textArea.select();
    
    const successful = document.execCommand('copy');
    document.body.removeChild(textArea);
    
    if (successful) {
      message("复制成功", { type: "success" });
    } else {
      message("复制失败", { type: "error" });
    }
  } catch (err) {
    console.error("复制失败:", err);
    message("复制失败", { type: "error" });
  }
};
</script>

<style lang="scss">
/* 基本样式 */
.text-container {
  position: relative; /* 父容器设置为相对定位 */
  display: block;
  padding: 0 10px;
  min-height: 24px; /* 确保容器有足够的高度 */
}

/* 内容区域 */
.content {
  padding-right: 30px; /* 为图标预留空间 */
  word-break: break-word; /* 允许文字换行 */
}

/* 复制按钮样式 */
.copy-button {
  position: absolute;
  top: 50%;
  right: 10px; /* 固定在最右侧并留出一些间距 */
  transform: translateY(-50%); /* 垂直居中 */
  color: #409eff;
  cursor: pointer;
  font-size: 16px;
  transition: all 0.3s;

  &:hover {
    color: #66b1ff;
  }
}

/* 使用伪类创建背景区域 */
.copy-button::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 32px; /* 背景宽度 */
  height: 32px; /* 背景高度 */
  background-color: rgba(0, 0, 0, .03); /* 背景颜色和透明度 */
  border-radius: 6px; /* 圆角效果 */
  z-index: -1; /* 确保背景区域在图标后面 */
  opacity: 0; /* 默认隐藏 */
  transition: opacity 0.3s; /* 平滑过渡效果 */
}

/* 悬停时显示背景区域 */
.copy-button:hover::after {
  opacity: 1; /* 显示背景 */
}
</style>

### 部署 Stable Diffusion 的准备工作 为了成功部署 Stable Diffusion,在本地环境中需完成几个关键准备事项。确保安装了 Python 和 Git 工具,因为这些对于获取源码和管理依赖项至关重要。 #### 安装必要的软件包和支持库 建议创建一个新的虚拟环境来隔离项目的依赖关系。这可以通过 Anaconda 或者 venv 实现: ```bash conda create -n sd python=3.9 conda activate sd ``` 或者使用 `venv`: ```bash python -m venv sd-env source sd-env/bin/activate # Unix or macOS sd-env\Scripts\activate # Windows ``` ### 下载预训练模型 Stable Diffusion 要求有预先训练好的模型权重文件以便能够正常工作。可以从官方资源或者其他可信赖的地方获得这些权重文件[^2]。 ### 获取并配置项目代码 接着要做的就是把最新的 Stable Diffusion WebUI 版本拉取下来。在命令行工具里执行如下指令可以实现这一点;这里假设目标路径为桌面下的特定位置[^3]: ```bash git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git ~/Desktop/stable-diffusion-webui cd ~/Desktop/stable-diffusion-webui ``` ### 设置 GPU 支持 (如果适用) 当打算利用 NVIDIA 显卡加速推理速度时,则需要确认 PyTorch 及 CUDA 是否已经正确设置好。下面这段简单的测试脚本可以帮助验证这一情况[^4]: ```python import torch print(f"Torch version: {torch.__version__}") if torch.cuda.is_available(): print("CUDA is available!") else: print("No CUDA detected.") ``` 一旦上述步骤都顺利完成之后,就可以按照具体文档中的指导进一步操作,比如调整参数、启动服务端口等等。整个过程中遇到任何疑问都可以查阅相关资料或社区支持寻求帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值