以纯文本形式复制到剪贴板

Copy to clipboard as plain text

本文关键字:复制 剪贴板 文本      更新时间:2023-09-26

我在Chrome扩展background.js中使用此代码将文本复制到用户的剪贴板:

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        if (request.command == "copy") {
            executeCopy(request.text);
            sendResponse({farewell: "copy request received"});
        }
    }
);
function executeCopy(text){
    var copyDiv = document.createElement('div');
    copyDiv.contentEditable = true;
    document.body.appendChild(copyDiv);
    copyDiv.innerHTML = text;
    copyDiv.unselectable = "off";
    copyDiv.focus();
    document.execCommand('SelectAll');
    document.execCommand("Copy", false, null);
    document.body.removeChild(copyDiv);
}

用格式复制文本。如何以无格式的纯文本复制文本?

您的问题代码包含一个称为XSS的常见安全问题。因为您接受了不受信任的输入并将其分配给.innerHTML,所以您允许攻击者在您的文档上下文中插入任意HTML。

幸运的是,攻击者不能在扩展的上下文中运行脚本,因为扩展的默认内容安全策略禁止内联脚本。这个CSP在Chrome扩展中强制执行,正是因为这样的情况,以防止XSS漏洞。

正确的转换HTML到文本的方式是通过DOMParser API。下面两个函数展示了如何将文本复制为文本,或者将HTML复制为文本:

// Copy text as text
function executeCopy(text) {
    var input = document.createElement('textarea');
    document.body.appendChild(input);
    input.value = text;
    input.focus();
    input.select();
    document.execCommand('Copy');
    input.remove();
}
// Copy HTML as text (without HTML tags)
function executeCopy2(html) {
    var doc = new DOMParser().parseFromString(html, 'text/html');
    var text = doc.body.textContent;
    return executeCopy(text);
}

注意.textContent完全忽略HTML标记。如果您想将<br> s解释为换行符,请使用非标准(但在Chrome中支持).innerText属性而不是.textContent

这里有两个例子,说明XSS如何被滥用,使用你问题中的executeCopy函数:

// This does not only copy "Text", but also trigger a network request
// to example.com!
executeCopy('<img src="http://example.com/">Text');
// If you step through with a debugger, this will show an "alert" dialog
// (an arbitrary script supplied by the attacker!!)
debugger;
executeCopy('<iframe src="data:text/html,<script>alert(/XXS-ed!/);<'/script>"></iframe>');