Html2canvas: ๊ต์ฐจ ๋„๋ฉ”์ธ ์ด๋ฏธ์ง€๊ฐ€ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Œ(CORS ๋˜๋Š” ํ”„๋ก์‹œ ์—†์Œ)

์— ๋งŒ๋“  2015๋…„ 05์›” 21์ผ  ยท  23์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: niklasvh/html2canvas

์•ˆ๋…•ํ•˜์„ธ์š”,

๋‹ค์Œ ์ฝ”๋“œ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋„๋ฉ”์ธ ๊ฐ„ ๋ Œ๋”๋ง์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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);
        }
    });

" http://www.playgroundmarkingsdirect.co.uk "์—์„œ " http://www.thermmark.co.uk "์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๊ณ  ํ•˜๋ฉด ์ด๋ฏธ์ง€๊ฐ€ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ๋ฅผ " http://www.thermmark.co.uk " ์›น์‚ฌ์ดํŠธ๋กœ ์˜ฎ๊ฒผ์„ ๋•Œ ๋ Œ๋”๋ง๋œ ์ด๋ฏธ์ง€(๋‘ ๋„๋ฉ”์ธ ๋ชจ๋‘ ์†Œ์œ )

์–ด๋–ค ์•„์ด๋””์–ด?

Needs More Information

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์–ด์ฉŒ๋ฉด useCORS ptoperty๋ฅผ true๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํฌ๋กœ์Šค ๋„๋ฉ”์ธ ์›น ์ฝ˜ํ…์ธ ๋ฅผ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  23 ๋Œ“๊ธ€

์–ด์ฉŒ๋ฉด useCORS ptoperty๋ฅผ true๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํฌ๋กœ์Šค ๋„๋ฉ”์ธ ์›น ์ฝ˜ํ…์ธ ๋ฅผ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

useCORS ํ•˜๋ฉด ์ด๋ฏธ์ง€ ์บก์ฒ˜๊ฐ€ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๊ฒช๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๋Š” ์™ธ๋ถ€ ๋„๋ฉ”์ธ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ ์‹คํŒจํ•˜์ง€ ์•Š๊ณ  ์บก์ฒ˜์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด์ƒํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ์ˆ˜์ •์„ ์‹œ๋„ ํ–ˆ์Šต๋‹ˆ๊นŒ? https://github.com/niklasvh/html2canvas/pull/554

allowTaint ๋ฅผ true๋กœ ์„ค์ •ํ•ด์•ผ ํ•˜์ง€๋งŒ ๋ Œ๋”๋ง๋œ ๊ฒฐ๊ณผ๋ฅผ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

userCORS ๋˜๋Š” proxy ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ์œ„ํ•ด ๋งŒ๋“  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@brcontainer ์ตœ์‹  ๋ฒ„์ „์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋‚ด ์ˆ˜์ • ์‚ฌํ•ญ์„ ์ฐธ์กฐํ•˜์„ธ์š” .

@Cristy94 ๋งž์•„์š” !! ํ›Œ๋ฅญํ•œ ์ˆ˜์ •! ๊ฐ์‚ฌ ํ•ด์š”!

์•ˆ๋…•ํ•˜์„ธ์š” @Cristy94 ,

๋‚ด HTML์˜ CMS(Contentful)์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜จ ๋‹ค์Œ ํ•ด๋‹น HTML์˜ PDF๋ฅผ ์ƒ์„ฑํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ƒ์„ฑ๋œ PDF์—์„œ ์ด๋ฏธ์ง€๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.(๊ต์ฐจ ์ถœ์ฒ˜ ๋ฌธ์ œ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค).
์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์ œ์•ˆํ•ด ์ฃผ์‹ญ์‹œ์˜ค.
์•„๋ž˜๋Š” ๋‚ด ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

ํ•จ์ˆ˜ ๋‹ค์šด๋กœ๋“œPDF() {
var canvasToImage = ํ•จ์ˆ˜(์บ”๋ฒ„์Šค){
var img = ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€();
var dataURL = ์บ”๋ฒ„์Šค.toDataURL('์ด๋ฏธ์ง€/png');
img.crossOrigin = "์ต๋ช…";
img.src = ๋ฐ์ดํ„ฐ URL;
์ด๋ฏธ์ง€ ๋ฐ˜ํ™˜;
};

var canvasShiftImage = ๊ธฐ๋Šฅ(oldCanvas,shiftAmt){
shiftAmt = parseInt(shiftAmt) || 0;
if(!shiftAmt){ oldCanvas ๋ฐ˜ํ™˜; }

var newCanvas = document.createElement('์บ”๋ฒ„์Šค');
newCanvas.height = oldCanvas.height - shiftAmt;
newCanvas.width = oldCanvas.width;
var ctx = newCanvas.getContext('2d');
ctx.mozImageSmoothingEnabled = ๊ฑฐ์ง“;
ctx.webkitImageSmoothingEnabled = ๊ฑฐ์ง“;
ctx.msImageSmoothingEnabled = ๊ฑฐ์ง“;
ctx.imageSmoothingEnabled = ๊ฑฐ์ง“;

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

๋ฐ˜ํ™˜ newCanvas;
};

var canvasToImageSuccess = ๊ธฐ๋Šฅ(์บ”๋ฒ„์Šค){
var pdf = ์ƒˆ๋กœ์šด jsPDF('l','px'),
pdfInternals = pdf.internal,
pdfPageSize = pdfInternals.pageSize,
pdfScaleFactor = pdfInternals.scaleFactor,
pdfPageWidth = pdfPageSize.width,
pdfPageHeight = pdfPageSize.height,
์ด PDF ๋†’์ด = 0,
htmlํŽ˜์ด์ง€ ๋†’์ด = ์บ”๋ฒ„์Šค.๋†’์ด,
htmlScaleFactor = canvas.width / (pdfPageWidth * pdfScaleFactor),
์•ˆ์ „๋ง = 0;

๋™์•ˆ(totalPdfHeight < htmlPageHeight && SafetyNet < 15){
var newCanvas = canvasShiftImage(์บ”๋ฒ„์Šค, totalPdfHeight);
pdf.addImage(newCanvas, 'png', 0, 0, pdfPageWidth, 0, null, '์—†์Œ');
// var alias = Math.random().toString(35);
// pdf.addImage(newCanvas, 0, 0, pdfPageWidth, 0, 'png', alias, 'NONE');

totalPdfHeight += (pdfPageHeight * pdfScaleFactor * htmlScaleFactor);

if(์ดPdfHeight < htmlํŽ˜์ด์ง€ ๋†’์ด){
pdf.addPage();
}
์„ธ์ดํ”„ํ‹ฐ๋„ท++;
}

var pageName = document.location.pathname.match(/[^/]+$/)[0];
pdf.save(ํŽ˜์ด์ง€์ด๋ฆ„ + '.pdf');
};

html2canvas($('๋ฐ”๋””')[0],
{
๋ Œ๋”๋ง: ํ•จ์ˆ˜(์บ”๋ฒ„์Šค){
CanvasToImageSuccess(์บ”๋ฒ„์Šค);
}
});
}

์ด๋ด, ๊ฑฐ๊ธฐ์— ๋Œ€ํ•œ ์ˆ˜์ • ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์—ฌ๊ธฐ์—์„œ๋„ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์€ CORS ์ด๋ฏธ์ง€ :(

์•ˆ๋…•ํ•˜์„ธ์š” ๋ฃจ์ฝ”ํ”„์ž…๋‹ˆ๋‹ค.

html2canvas ํ•จ์ˆ˜์—์„œ ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์ด ํ™•์‹คํžˆ ํšจ๊ณผ๊ฐ€ ์žˆ์„ ๊ฑฐ๋ผ๊ณ  ๋ฏฟ์œผ์„ธ์š” :)

html2canvas($('#div_pdf')[0],
{
useCORS: true, // ํ•จ์ˆ˜์—์„œ ์ด ์˜ต์…˜์„ ์ „๋‹ฌํ•˜๋ฉด Cross origin ์ด๋ฏธ์ง€๊ฐ€ ๋‹ค์šด๋กœ๋“œ๋œ PDF ๋ฒ„์ „์—์„œ ์ œ๋Œ€๋กœ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค.
onrendered: ํ•จ์ˆ˜(์บ”๋ฒ„์Šค) {
CanvasToImageSuccess(์บ”๋ฒ„์Šค);
}
});
์ถ”๊ฐ€ ์ •๋ณด๋Š” ์•„๋ž˜ URL์—์„œ html2canvas ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.
https://html2canvas.hertzen.com/documentation.html

์•ˆ๋…•ํ•˜์„ธ์š” @gauravmishra24 , ๋ถˆํ–‰ํžˆ๋„ ์ด๊ฒƒ์€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ์„œ๋ฒ„์— ํ”Œ๋ž˜๊ทธ๊ฐ€ ์žˆ๋Š” ์„œ๋ฒ„์˜ ์ด๋ฏธ์ง€๋ฅผ ํฌํ•จํ•˜๊ณ  ์‹ถ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Access-Control-Allow-Origin: *

์„ค์ • ๋˜์ง€ ์•Š์Œ

:(

์•ˆ๋…•ํ•˜์„ธ์š” ๋ฃจ์ฝ”ํ”„์ž…๋‹ˆ๋‹ค.

์ฝ”๋“œ ์Šค๋‹ˆํŽซ์„ ๊ฒŒ์‹œํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๊ฐ™์€ ๋ชจ์Šต์„ ๋” ์ž˜ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก.....

์•ˆ๋…•ํ•˜์„ธ์š”,

์ด์— ๋Œ€ํ•œ ์ˆ˜์ • ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๊นŒ? useCORS๋ฅผ true๋กœ ์„ค์ •ํ•ด๋„ ์ด๋ฏธ์ง€๊ฐ€ ๋‹ค์šด๋กœ๋“œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์—ฌ์ „ํžˆ ๊ต์ฐจ ์ถœ์ฒ˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ๋ถ„์‚ฐ html2Canvas.js ํŒŒ์ผ์˜ Cristy94 ์†”๋ฃจ์…˜์— ๋Œ€ํ•ด ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ถ„์‚ฐ ํŒŒ์ผ์—์„œ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•œ ํ›„์—๋„ https://github.com/niklasvh/html2canvas/pull/554/commits/87d44359be73075ba4d5f36d6e1c8b88b7444402์— ๋”ฐ๋ผ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ”„๋ก์‹œ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ๋Œ€์•ˆ์˜ ๊ฒฝ์šฐ Angular 2 ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ ์†”๋ฃจ์…˜์ด ์žˆ์Šต๋‹ˆ๊นŒ?
ํ˜„์žฌ ์‚ฌ์ดํŠธ(https://github.com/niklasvh/html2canvas/wiki/Proxies) ๋ชฉ๋ก์— ์—†์Šต๋‹ˆ๋‹ค!

์ด๊ฒƒ์€ ์—ฌ์ „ํžˆ v1.0.0 ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด jsfiddle์— ๋Œ€ํ•œ ์˜ˆ๋ฅผ

์ด ํ˜ธ๋Š” ์›์ €์ž์˜ ์ถ”๊ฐ€ ์ •๋ณด ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™์œผ๋กœ ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๋ฌธ์ œ์— ์žˆ๋Š” ์ •๋ณด๋งŒ์œผ๋กœ๋Š” ์กฐ์น˜๋ฅผ ์ทจํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•œ ์ •๋ณด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋” ์กฐ์‚ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•„์š”ํ•œ ๋‹ต๋ณ€์ด ์žˆ๊ฑฐ๋‚˜ ์ฐพ์œผ๋ฉด ์—ฐ๋ฝํ•ด ์ฃผ์‹ญ์‹œ์˜ค.

@niklasvh ๋‹ค์Œ์€ v1.0.0์ด ํฌํ•จ๋œ codepen์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค.
https://codepen.io/Onlylonger/pen/ppjPKX
๊ฐ™์€ ์งˆ๋ฌธ . ๋‹น์‹ ์—๊ฒŒ

๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์•Œ๊ณ  ์žˆ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ๋‹ค๋ฅธ ์„œ๋ฒ„ ์š”์ฒญ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ”„๋ก์‹œ์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ์˜ˆ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

@vinayistar ๋‚ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค https://github.com/niklasvh/html2canvas/issues/1544#issuecomment -435640901 ๋งํฌ

useCORS ๋ฐ img ์†์„ฑ crossOrigin:anonymous

{ useCORS: false, allowTaint: true } ์ด๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค

์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋‚˜์˜ ํ•ด๊ฒฐ์ฑ…์€ ์ด๋ฏธ์ง€ src๋ฅผ 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 ์ด ์ƒ˜ํ”Œ์„

@nishanta454
์ œ๊ฐ€ ์ž‘์„ฑํ•œ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. html2canvas๋Š” ๊ต์ฐจ ์›์  ์ด๋ฏธ์ง€๋ฅผ ๋ Œ๋”๋ง ํ•ฉ๋‹ˆ๋‹ค.
์ด ์˜ˆ์—์„œ๋Š” cors-anywhere ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ CORS ํ—ค๋”๋ฅผ ํ”„๋ก์‹œ ์ด๋ฏธ์ง€ ์š”์ฒญ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€์žฅ ๋จผ์ € ํ•„์š”ํ•œ ๊ฒƒ์€ ์ด๋ฏธ์ง€ ํŒŒ์ผ์— ๋Œ€ํ•œ ๊ต์ฐจ ์ถœ์ฒ˜ ์•ก์„ธ์Šค๋ฅผ ํ—ˆ์šฉํ•˜๋„๋ก ๊ตฌ์„ฑ๋œ Access-Control-Allow-Origin ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ ํ˜ธ์ŠคํŒ…ํ•˜๋„๋ก ๊ตฌ์„ฑ๋œ ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค.
CORS_enabled_image์—์„œ

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰