CORS error for adding image from another domain in jsPDF in Angular 8

Viewed 5176

I want to use some images in jsPdf. These images come from another domain (API). This is my code:

let img = new Image();
img.src = 'myUrl';
docPdf.addImage(img, 'JPEG', col, row, width, height, 'FAST');

But I receive this error:

Access to image at 'http://127.0.0.1:8000/some-url' from origin 'http://127.0.0.1:4000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

ERROR Error: Supplied Data is not a valid base64-String jsPDF.convertStringToImageData 
at Object.x.convertStringToImageData (jspdf.min.js:50)

Then I add crossOrigin to my url but I also receive that error.

img.crossOrigin = 'anonymous';

or img.crossOrigin = 'Anonymous';

I also set cors settings in backend:

CORS_ORIGIN_ALLOW_ALL = True
2 Answers

If your backend is already accepting all origins, and you are setting img.crossOrigin = 'anonymous', you could try adding a random parameter to your image URL:

img.src = imgUrl + '?r=' + Math.floor(Math.random()*100000);

It looks like the browser already has your image cached, but it won't let any javascript read it from the disk. Adding a random param to the imageURL, it will miss the browser cached image and download it again from the server.

For clarification I created a codesandbox.

I usually add my images as base64encoded dataurls. If images are from a different domain (like when you stored the link to the picture in your db), I convert the picture to baset64 client side with the following method:

toDataURL(url, callback) {
      var xhr = new XMLHttpRequest();
      xhr.onload = function() {
        var reader = new FileReader();
        reader.onloadend = function() {
          callback(reader.result);
        };
        reader.readAsDataURL(xhr.response);
      };
      xhr.open("GET", url);
      xhr.responseType = "blob";
      xhr.send();
    },

In the created() method (or just when you need the image to be converted to base64), you can set a url property that's declared in the data obj:

created() {
    this.toDataURL(this.imgUrl, data => {
      this.imgAsBase64 = data;
    });
  }

Then simply add the image:

doc.addImage(this.imgAsBase64, "jpg", 10, 10);

And ur done.

Related