ExecCommand ('copy') not working in Ajax / XHR callback?

(Tested using Chrome 44)

Desired behavior . Make an XHR request, put the result in the text area, select the text and copy to the clipboard.

Actual behavior . On a successful request, XHR places the result in the text area and selects it, but does not copy the result to the clipboard. But if I initiate a copy outside the XHR callback, it works.

Example html page:

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> 

If you click the "Get data and copy text area" button, the data will be successfully extracted, but not copied. If you click the Copy Text Area button, the text will be copied as expected. I tried many query / copy combinations to try to get it to work, but to no avail (including programmatically pressing the copy button after data extraction). Does anyone know what is going on here? Is it a security feature or something else?

I do not want the user to have to press two buttons to extract and copy, if possible.

+5
javascript html ajax copy execcommand
source share
2 answers

You can only invoke a copy in the system clipboard in direct response to a trusted user action, such as a click event.

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

+12
source share

If you do synchronous XMLHttpRequest, this will work. You just need to add false as the third parameter in 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> 
+7
source share

All Articles