Wednesday 11 September 2019

Getting through Tainted Canvas or CORS error in client side setup (vanilla Javascript, Local files, no Server Side Settings)

Okay, I was making a small, totally client side solution to generate final viva sheets. The application required users to upload an excel file, then it reads the data and shows some check boxes, user can select the desired check boxes and then click a button to download a word file (.docx). I was using TinyMCE and a bit of vanilla Javascript to generate the content inside the Tiny MCE HTML Editor and downloading the file:



Things were going well, but as soon as I used the company logo inside the editor, it will always throw tinted canvas error first and if I set my image tag attribute as crossorigin='anonymous', it will then throw CORS error when downloading the file:




I was completely stumped with this issue, as I only needed to access a small logo file inside the same folder but there was simply no solution available. As all solutions require a local or remote web server to host file with CORS enabled settings etc. I simply did not needed it as I wanted the users to do it completely on their PCs without even Internet working (just the excel file as input).

So I had to hack my way around, first thing worked for me was, to create a batch file and put the MS DOS commands to start chrome with some arguments to disable security and allow local file access. And I had to include the arguments to launch a new instance with Default profile, so that the security and allow file access properly work the command is:
start chrome /new-window file:///%CD%/vsheets.html --allow-file-access-from-files --allow-file-access --allow-cross-origin-auth-prompt --user-data-dir=Default


It worked well, as there was no error and word file downloaded correctly. The only minor issue was it would create around 60MB new folder having Default chrome profile.

Then actually GOD helped me, I clicked an image on google, and it opened

in a new window with a weired and long URL starting with: 
data:image/png;base64,aASilkuhkjhkjhkj....

I had no idea about it, but when searched, I came to know you can actually put simple text inside image tag src attribute and browser will convert it to an image. So I used  https://www.base64-image.de/ to upload my image, get it converted to base64 and copied the generated URL inside my src attribute, and voila, it worked like a charm. No more tainted canvas or CORS error and so was the best solution. My image tag finally was:
<img src='data:image/jpeg;base64,/9j/4AAZJRgABAQAAA.....' alt='' >


But I didnt find it any where on stackoverflow or other search as all were only suggesting to setup a local server or access the file from some remote server/link having CORS enabled on that image/resource. So I thought my little blog could help some one in similar situation.


The only draw back of this solution is it will slow down the page depending upon the size of image that is converted. But my image was very tiny (60 x 37 pixels logo) so there was no performance drop at all (even I reduced it further using some other free online services to reduce JPG size, before generating base64 text).


Good luck.