bernd-wechner / Copy-with-Style

A single file client-side JavaScript class that supports copying fully styled HTML elements to the clipboard
Other
7 stars 1 forks source link

HTML not copied #1

Closed CameronSima closed 1 year ago

CameronSima commented 2 years ago

Neat project! However this doesn't seem to work for me -- for one, it's not able to get remote stylesheets:

SecurityError: CSSStyleSheet.cssRules getter: Not allowed to access cross-origin stylesheet

Most webpages will have externally-sourced css.

Also, what does get copied isn't html. When I run this code on google.com I get:

let btn = document.createElement("button");
btn.innerHTML = "Click Me";
btn.id = "copy-button"
document.body.appendChild(btn);

const clipboard = new Copy_With_Style({ button: document.getElementById("copy-button"),
                                        element: document.querySelector('body'),
                                        debug: true
                                      }); 
About
Store
GmailImages

Advertising
Business
How Search works
Carbon neutral since 2007
Privacy
Terms
Settings
Click Me
bernd-wechner commented 2 years ago

Thanks for the report. I've certainly used it to get remote stylesheets in past. That cross-origin error is not new to me, and it crops up all over the place of late and relates to the website you're on and its server configuration.

It's called a CORS issue:

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Alas there's nothing a JS lib can do about that. It is all about the respective webserver configurations. They have denied Javascript access to remoter resources for security reasons and relates to the Access-Control-Allow-Origin header that the server delivers to hte browser and crucially the version of browser because CORS is a relatively young suite of security measures (but all modern up to date browser have it implemented).

As to what is copied, it copies both HTML and text to the clipboard, and what is pasted depends on what the receiving context (that you paste into expects - HTML or text). Here's how I inspect the clipboard to see what's on it:

https://dev.to/thumbone/inspecting-the-clipboard-on-linux-3hb0

But to test it, I typically paste into an email client (I use Thunderbird) to see the HTML contents and a text editor to see the text contents.

Hope that helps a little.

CameronSima commented 2 years ago

Gotcha, yeah I suppose there's no way around CORS when calling from the browser

bernd-wechner commented 2 years ago

Gotcha, yeah I suppose there's no way around CORS when calling from the browser

Nope. It's s server-side security setting. I'm not entirely sure why it prevents JavaScript from loading remote CSS files by default, but I think it might. The obvious security risk is when JavaScript loads remote JavaScript. Mainly because your web page can already have third party JavaScript on it (injected by any browser add-ons you like and use or ones you don't know about (malware) and then if they can load remote JavaScript that is further injection of JavaScript and so on.

For some reason (I haven't studied it all too closely) the onus for all this JavaScript security falls with the server admin, and the only reason that springs to mind readily is that the website owner may want to provide safe web services. Imagine you're a bank. You don't want the security of your client's account access to be governed by end-users browser security settings, you want control over that at the web server side.

And so CORS settings are sent in the HTTP headers or a response, and browsers honour them. The interesting thing here is that in the end client side (browser) does enforce the CORS request and could be written to relax it, technically. But as far as I know the common browser engines (that browsers use, don't implement that client side flexibility, and if they did, it would be buried deep in debugging tools for skilled use not casual end user access).

There are two ways to get around it in your case for CSS:

  1. What I do, is any CSS that I want to make available to Copy With Style, I serve locally. I don't use a CDN. You can copy any CDN served CSS locally and serve it there too easily enough.

  2. If you have access to either the webserver or the admins and they are sympathetic, relax the CORS security settings that it sends. They can be set on a site specific basis even page specific it's not like they have to be relaxed across all sites a given server serves and in fact the server can also be configure to let you set them ... though you'd need access to (be using) a web framework server side that compiles the whole HTTP response (the web server can honour framework set CORS headers and in fact that may even be the default confiuration, which will be server dependent - i.e. is it being served by Apache, nginx, lighttpd, IIS, or some other server?)