Hugo Copy Code

使用hugo建站, 点击代码块中右上角的 Copy按钮时, 发现没有生效

仔细对比了一下stack主题的config文件以及content文件夹下的markdown源码, 复制代码并不需要额外特殊设置, 于是打开控制台, 发现确实有代码报错, 报错信息如下

Uncaught TypeError: Cannot read properties of undefined (reading 'writeText')
    at HTMLButtonElement.<anonymous> (main.js:4:429)
(匿名) @ main.js:4
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
let r = document.querySelectorAll(".article-content div.highlight")
    , i = "Copy"
    , n = "Copied!";
r.forEach(o=>{
    let s = document.createElement("button");
    s.innerHTML = i,
    s.classList.add("copyCodeButton"),
    o.appendChild(s);
    let a = o.querySelector("code[data-lang]");
    !a || s.addEventListener("click", ()=>{
        navigator.clipboard.writeText(a.textContent).then(()=>{  //此行报错
            s.textContent = n,
            setTimeout(()=>{
                s.textContent = i
            }
            , 1e3)
        }
        ).catch(d=>{
            alert(d),
            console.log("Something went wrong", d)
        }
        )
    }
    )
}
)

代码中可以看到, 使用 navigator.clipboard API 来实现复制

于是搜索了一下这个 API , 在阮一峰老师的一篇文章 剪贴板操作 Clipboard API 教程 - 阮一峰的网络日志 找到了答案

如果navigator.clipboard属性返回undefined,就说明当前浏览器不支持这个 API。

由于用户可能把敏感数据(比如密码)放在剪贴板,允许脚本任意读取会产生安全风险,所以这个 API 的安全限制比较多。

首先,Chrome 浏览器规定,只有 HTTPS 协议的页面才能使用这个 API。不过,开发环境(localhost)允许使用非加密协议。

其次,调用时需要明确获得用户的许可。权限的具体实现使用了 Permissions API,跟剪贴板相关的有两个权限:clipboard-write(写权限)和clipboard-read(读权限)。“写权限"自动授予脚本,而"读权限"必须用户明确同意给予。也就是说,写入剪贴板,脚本可以自动完成,但是读取剪贴板时,浏览器会弹出一个对话框,询问用户是否同意读取。

由于我是使用hugo生成了页面文件, 然后用nginx搭建静态网站, 在nginx中同时监听了 http 和 https

访问时直接输入域名, 实际访问的是 http 协议的地址, 无法使用这个API

在地址栏完整输入了 https:// 开头的协议之后, 果然可以成功复制内容了