Html2canvas: Cross Domain images not rendering (No CORS or proxy)

Created on 21 May 2015  ·  23Comments  ·  Source: niklasvh/html2canvas

Hi,

Using the following code images are not rendering cross-domain.

html2canvas($(".canvas-surround"), {
        logging: true,
        width: 1920 * getScale(),
        height: 1080 * getScale(),
        useCORS: false,
        onrendered: function(canvas) {

            var bottomCtx = canvas.getContext("2d");
            var topCtx = canvas.getContext("2d");
            var bData = bottomCtx.getImageData(0, 0, canvas.width, canvas.height);
            var tData = topCtx.getImageData(0, 0, canvas.width, canvas.height);

            var merged = mergeData(bData, tData);

            bottomCtx.putImageData(merged, 0, 0);

            var newImg = canvas.toDataURL("image/png");
            console.log(newImg);
            var blob = b64toBlob(newImg, "image/png");
            console.log(blob);

            var blobUrl = URL.createObjectURL(blob);

            console.log(blobUrl);

            downloadURI(blobUrl);
        }
    });

Whilst trying to grab images from "http://www.thermmark.co.uk" from "http://www.playgroundmarkingsdirect.co.uk" the images would not render.

When I moved the code over to the "http://www.thermmark.co.uk" website the images rendered (I own both domains)

Any ideas?

Needs More Information

Most helpful comment

Maybe You should use useCORS ptoperty as true, it intended for crossdomained web content

All 23 comments

Maybe You should use useCORS ptoperty as true, it intended for crossdomained web content

Using useCORS fails the image grab. The issue I'm having is strange as it doesn't fail to get the image from the external domain, it just doesn't render it in the capture.

Probably should set allowTaint to true, but then you can't export the rendered result.

I don't understand why not use the userCORS or proxy... They were just created for such problems.

@brcontainer Because they don't work in the latest version, see my fix: https://github.com/niklasvh/html2canvas/pull/554

@Cristy94 Sure!! Great fix! Thanks!

Hi @Cristy94,

I am fetching the images from CMS(Contentful) in my HTML and then trying to generate PDF of that HTML.
But in the generated PDF, images are missing.(seems to be an issue of cross origin).
Please suggest me how can i get rid of this issues.
Below is my code-:

function downloadPDF() {
var canvasToImage = function(canvas){
var img = new Image();
var dataURL = canvas.toDataURL('image/png');
img.crossOrigin = "Anonymous";
img.src = dataURL;
return img;
};

var canvasShiftImage = function(oldCanvas,shiftAmt){
shiftAmt = parseInt(shiftAmt) || 0;
if(!shiftAmt){ return oldCanvas; }

var newCanvas = document.createElement('canvas');
newCanvas.height = oldCanvas.height - shiftAmt;
newCanvas.width = oldCanvas.width;
var ctx = newCanvas.getContext('2d');
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;

var img = canvasToImage(oldCanvas);
ctx.drawImage(img,0, shiftAmt, img.width, img.height, 0, 0, img.width, img.height);

return newCanvas;
};

var canvasToImageSuccess = function(canvas){
var pdf = new jsPDF('l','px'),
pdfInternals = pdf.internal,
pdfPageSize = pdfInternals.pageSize,
pdfScaleFactor = pdfInternals.scaleFactor,
pdfPageWidth = pdfPageSize.width,
pdfPageHeight = pdfPageSize.height,
totalPdfHeight = 0,
htmlPageHeight = canvas.height,
htmlScaleFactor = canvas.width / (pdfPageWidth * pdfScaleFactor),
safetyNet = 0;

while(totalPdfHeight < htmlPageHeight && safetyNet < 15){
var newCanvas = canvasShiftImage(canvas, totalPdfHeight);
pdf.addImage(newCanvas, 'png', 0, 0, pdfPageWidth, 0, null, 'NONE');
// var alias = Math.random().toString(35);
// pdf.addImage(newCanvas, 0, 0, pdfPageWidth, 0, 'png', alias, 'NONE');

totalPdfHeight += (pdfPageHeight * pdfScaleFactor * htmlScaleFactor);

if(totalPdfHeight < htmlPageHeight){
pdf.addPage();
}
safetyNet++;
}

var pageName = document.location.pathname.match(/[^/]+$/)[0];
pdf.save(pageName + '.pdf');
};

html2canvas($('body')[0],
{
onrendered: function(canvas){
canvasToImageSuccess(canvas);
}
});
}

Hey, will there be a fix for that? CORS images not rendered here as well :(

Hi Rookev,

You can do so by passing one of the option in html2canvas function. And trust me this will surely work :)

html2canvas($('#div_pdf')[0],
{
useCORS: true, //By passing this option in function Cross origin images will be rendered properly in the downloaded version of the PDF
onrendered: function (canvas) {
canvasToImageSuccess(canvas);
}
});
For further info you can have a look at the documentation of the html2canvas library on below URL-:
https://html2canvas.hertzen.com/documentation.html

Hi @gauravmishra24, unfortunately this does not work. The problem is that I want to include images from a server where the server has the flag

Access-Control-Allow-Origin: *

not set

:(

Hi Rookev,

Could you please post your code snippet?

So that I can have a better look on the same.....

Hi,

Is there any fix for this? Even with useCORS set to true, images are not getting downloaded. Still get the cross-origin error as mentioned above.

Also, not sure about Cristy94's solution in distributed html2Canvas.js file. Even after changing code in distributed file, as per https://github.com/niklasvh/html2canvas/pull/554/commits/87d44359be73075ba4d5f36d6e1c8b88b7444402 it doesn't work either.

For the other alternative, with proxy settings, is there any solution for angular 2 application?
Current site (https://github.com/niklasvh/html2canvas/wiki/Proxies) list doesn't have it!

Is this still an issue with v1.0.0? If so, could you please share an example on jsfiddle.

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.

@niklasvh Here is my example on codepen with v1.0.0:
https://codepen.io/Onlylonger/pen/ppjPKX
the same quesiton . thx you

Is there any other plugin anyone knows. This was not working with different servers request. No proper example given for proxy.

@vinayistar you can try my changes see link https://github.com/niklasvh/html2canvas/issues/1544#issuecomment-435640901

Using useCORS and set img attribute crossOrigin:anonymous

{ useCORS: false, allowTaint: true } this is worked for me

My solution to this problem is converting the image src to Base64

const img = document.querySelector('#img')
fetch(img.src)
  .then(res => res.blob())
  .then(blob => new Promise((resolve, reject) => {
      const reader = new FileReader;
      reader.onerror = reject;
      reader.onload = () => {
        resolve(reader.result);
      };
      reader.readAsDataURL(blob);
    })
  )
  .then(dataURL => {
    img.src = dataURL
    return html2canvas(element)
  } )

@todoi Can you provide the sample of this with jspdf.

@nishanta454
This is the example that I wrote. html2canvas render cross origin images.
In this example, i use cors-anywhere to add CORS headers to proxy image request.

The first thing we need is a server that's configured to host images with the Access-Control-Allow-Origin header configured to permit cross-origin access to image files.
from CORS_enabled_image

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stevencherry1 picture stevencherry1  ·  3Comments

dking3876 picture dking3876  ·  4Comments

yasergh picture yasergh  ·  5Comments

AlphaDu picture AlphaDu  ·  4Comments

ABHIKSINGHH picture ABHIKSINGHH  ·  3Comments