title: CORS errors trying to convert remote image to base64 data
body: <p>I need to convert a remote image into base64 given its URL, but I am running in to CORS errors and not sure how to work around.</p>
  
  <p>I've followed some of the solutions on this question: <a href="https://stackoverflow.com/questions/6150289/how-to-convert-image-into-base64-string-using-javascript">How to convert image into base64 string using javascript</a></p>
  
  <p>My example image is: <a href="https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg" rel="noreferrer">https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg</a></p>
  
  <p><strong>Approach 1 (FileReader):</strong></p>
  
  <pre><code>function 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();
  }
  
  toDataUrl('https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg', function(data) { console.log(data)} );
  </code></pre>
  
  <p>This produces the error: </p>
  
  <blockquote>
    <p>XMLHttpRequest cannot load
    <a href="https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg" rel="noreferrer">https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg</a>. No
    'Access-Control-Allow-Origin' header is present on the requested
    resource. Origin '<a href="http://stackoverflow.com">http://stackoverflow.com</a>' is therefore not allowed
    access.</p>
  </blockquote>
  
  <p><strong>Approach 2 (Canvas)</strong></p>
  
  <pre><code>function toDataUrl(src, callback, outputFormat) {
    var img = new Image();
    img.crossOrigin = 'use-credentials';
    img.onload = function() {
      var canvas = document.createElement('CANVAS');
      var ctx = canvas.getContext('2d');
      var dataURL;
      canvas.height = this.height;
      canvas.width = this.width;
      ctx.drawImage(this, 0, 0);
      dataURL = canvas.toDataURL(outputFormat);
      callback(dataURL);
    };
    img.src = src;
    if (img.complete || img.complete === undefined) {
      img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
      img.src = src;
    }
  }
  toDataUrl('https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg', function(data) { console.log(data)} );
  </code></pre>
  
  <p>Produces a similar error when trying to load the image:</p>
  
  <blockquote>
    <p>Access to Image at
    '<a href="https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg" rel="noreferrer">https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg</a>'
    from origin '<a href="http://stackoverflow.com">http://stackoverflow.com</a>' has been blocked by CORS
    policy: No 'Access-Control-Allow-Origin' header is present on the
    requested resource. Origin '<a href="http://stackoverflow.com">http://stackoverflow.com</a>' is therefore not
    allowed access.</p>
  </blockquote>
  
  <p>Also tried with:</p>
  
  <pre><code>img.crossOrigin = 'anonymous';
  </code></pre>
  
  <p>And got the same result.</p>
  
  <p><strong>Approach 3 (Canvas using img element):</strong></p>
  
  <pre><code>img = document.createElement('img');
  img.onload = function() {
      var canvas = document.createElement('CANVAS');
      var ctx = canvas.getContext('2d');
      var dataURL;
      canvas.height = this.height;
      canvas.width = this.width;
      ctx.drawImage(this, 0, 0);
      dataURL = canvas.toDataURL('image/jpg');
      console.log(dataURL);
  };
  img.src = 'https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg';
  </code></pre>
  
  <p>This way at least loads the image but fails on calling toDataURL with:</p>
  
  <blockquote>
    <p>Uncaught DOMException: Failed to execute 'toDataURL' on
    'HTMLCanvasElement': Tainted canvases may not be exported.
        at HTMLImageElement.img.onload (:9:22)</p>
  </blockquote>
  
  <p>As an aside, I'm not sure exactly what the CORS policy is protecting against here. Suppose there is some kind of malicious payload that could trigger an exploit. We still load and display the image in the DOM and why would we trust CORS headers set by the same endpoint?</p>
  
  <p>Does anyone know of any solutions to this problem? </p>
  
  <p>Thanks for any help.</p>