【问题标题】:execCommand('copy') does not work in Ajax / XHR callback?execCommand('copy') 在 Ajax / XHR 回调中不起作用?
【发布时间】:2015-08-10 17:47:58
【问题描述】:

(使用 Chrome 44 测试)

期望行为:发出 XHR 请求,将结果放入文本区域,选择文本,然后复制到剪贴板。

实际行为:在成功的 XHR 请求时,将结果放入文本区域并选择它,但无法将结果复制到剪贴板。但是如果我在 XHR 回调之外启动复制,它就可以工作。

示例 html 页面:

var selectAndCopy = function() {
  // Select text
  var cutTextarea = document.querySelector('#textarea');
  cutTextarea.select();
  // Execute copy
  var successful = document.execCommand('copy');
  var msg = successful ? 'successful' : 'unsuccessful';
  console.log('Cutting text command was ' + msg);
};

var fetchCopyButton = document.querySelector('#fetch_copy');
fetchCopyButton.addEventListener('click', function(event) {
  var xhr = new XMLHttpRequest();
  xhr.open('get', 'http://httpbin.org/ip');
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        // Set text
        var textarea = document.querySelector('#textarea');
        textarea.value = xhr.responseText;

        selectAndCopy();
      }
    }
  };
  xhr.send();
});

var copyButton = document.querySelector('#copy');
copyButton.addEventListener('click', function(event) {
  selectAndCopy();
});
<html>

<head>
</head>

<body>
  <p>
    <textarea id="textarea">Hello, I'm some text!</textarea>
  </p>
  <p>
    <button id="fetch_copy">Fetch Data and Copy Textarea</button>
    <button id="copy">Copy Textarea</button>
  </p>
</body>

</html>

如果您按下“获取数据并复制文本区域”按钮,则数据成功获取但未复制。如果您按下“复制文本区域”按钮,则会按预期复制文本。我尝试了许多请求/复制的组合来尝试让它工作但无济于事(包括在获取数据后以编程方式按下复制按钮)。有谁知道这里发生了什么?这是安全功能还是什么?

如果可能的话,我不希望用户必须按两个按钮来获取和复制。

【问题讨论】:

  • 那你最后是怎么解决的呢?你能更新一下问题吗?
  • @ChrisGeo 我最终只选择了文本(但没有复制它)。我意识到如果我在他们的复制缓冲区中覆盖了某些内容,用户可能不会高兴。 Trevor 在下面的回答看起来会起作用(如果您对同步 XHR 没问题)
  • 这个问题在我的回答中解决了 :) 这里:stackoverflow.com/questions/43380921/…
  • 也许,你可以做一些我在这里提到的事情:SOLVED: document execCommand copy not working with AJAX
  • 如果操作是从trusted 事件发起的,这里有一个使用setTimeout 的黑客攻击:stackoverflow.com/a/40826549/3649573

标签: javascript html ajax copy execcommand


【解决方案1】:

您只能触发复制到系统剪贴板以直接响应受信任的用户操作,例如 click 事件。

规格:http://www.w3.org/TR/clipboard-apis/#integration-with-rich-text-editing-apis

【讨论】:

【解决方案2】:

免责声明:不建议在主线程上使用同步 XMLHttpRequest。请阅读this 并确保在使用此解决方案之前知道自己在做什么。不建议将其用于生产。

如果您使 XMLHttpRequest 同步,这将起作用。您只需将false 作为第三个参数添加到xhr.open(...)

var selectAndCopy = function() {
  // Select text
  var cutTextarea = document.querySelector('#textarea');
  cutTextarea.select();
  // Execute copy
  var successful = document.execCommand('copy');
  var msg = successful ? 'successful' : 'unsuccessful';
  console.log('Cutting text command was ' + msg);
};

var fetchCopyButton = document.querySelector('#fetch_copy');
fetchCopyButton.addEventListener('click', function(event) {
  var xhr = new XMLHttpRequest();
  xhr.open('get', 'http://httpbin.org/ip', false);
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        // Set text
        var textarea = document.querySelector('#textarea');
        textarea.value = xhr.responseText;

        selectAndCopy();
      }
    }
  };
  xhr.send();
});

var copyButton = document.querySelector('#copy');
copyButton.addEventListener('click', function(event) {
  selectAndCopy();
});
<html>

<head>
</head>

<body>
  <p>
    <textarea id="textarea">Hello, I'm some text!</textarea>
  </p>
  <p>
    <button id="fetch_copy">Fetch Data and Copy Textarea</button>
    <button id="copy">Copy Textarea</button>
  </p>
</body>

</html>

【讨论】:

  • 同步 XHR 通常是个坏主意,但如果没有它,就很难找到一种方法来一步到位。此外,您还会在 Chrome 的控制台中收到有关同步 XHR 请求的警告。
  • 是的,这是个坏主意,但我已经看到了同步 XHR 的工作原理!当我将它设置为异步时,Firefox 抱怨“document.execcommand('copy') 被拒绝,因为它不是从短期运行的用户生成的事件处理程序内部调用的”,但是,当 Ajax 调用同步时没有问题! !可能是什么原因?
猜你喜欢
  • 1970-01-01
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 2021-02-01
  • 2018-11-28
相关资源
最近更新 更多