tsayen / dom-to-image

Generates an image from a DOM node using HTML5 canvas
Other
10.33k stars 1.68k forks source link

Error: SecurityError: DOM Exception 18 #40

Open kevinchiu opened 8 years ago

kevinchiu commented 8 years ago

Error: SecurityError: DOM Exception 18

I seem to be getting this error only in Safari when I try to save a node. The node is a div with a fixed height and width, but with nothing in it.

OS X El Capitan 10.11.5 (15F34) Safari Version 9.1.1 (11601.6.17)

teamco commented 8 years ago

The same issue Error: SecurityError: DOM Exception 18 code: 18 column: 648 line: 30 message: "SecurityError: DOM Exception 18" name: "SecurityError" stack: "toDataURL@[native code]↵↵promiseReactionJob@[native code]"

svenvandescheur commented 8 years ago

I also ran into this issue, has anyone managed to work around it yet?

tsayen commented 8 years ago

@svenvandescheur could you please put together a jsfiddle that fails for you?

acoyfellow commented 8 years ago

Still digging, but this fiddle will re-produce "SecurityError: DOM Exception 18" for me, on desktop Safari, mobile everything (Opera, FF, Chrome, Safari), but it works as expected with Chrome on desktop.

https://jsfiddle.net/acoyfellow/Lggtwjbb/1/

tsayen commented 8 years ago

sorry to say, but I cannot reproduce that since don't own a Mac :smile:
anyone with a Mac want to make a PR fixing this issue?

thienhv295 commented 8 years ago

The same issue :(. Has anyone fix it?

kevinchiu commented 8 years ago

@tsayen You can try using the Midori browser on Linux or Windows: http://midori-browser.org/

WingGao commented 8 years ago

After searching the web, I couldn't find a satisfactory solution. So I just use a SVG to replace.

//line95
    function toPng(node, options) {
        return draw(node, options || {})
            .then(function (result) {
                try {
                    var image = result.canvas.toDataURL("image/png");
                    return image;
                } catch (err) {
                    console.warn(err);
                    return result.svg.src;
                }
            });
    }
//line 135
function draw(domNode, options) {
        return toSvg(domNode, options)
            .then(util.makeImage)
            .then(util.delay(100))
            .then(function (image) {
                var canvas = newCanvas(domNode);
                // after this, Canvas’ origin-clean is DIRTY
                // safari will throw 'SecurityError: DOM Exception 18'
                // but it can use 'data:images/svg+xml'
                canvas.getContext('2d').drawImage(image, 0, 0);
                return {canvas: canvas, svg: image};
            });
...
thienhv295 commented 8 years ago

@WingGao: Actually, I had changed like you. And then it's show on browser only, but I cannot save image to file on server (cannot save data:images/svg+xml to image file). Do you have any solution for this issue?

WingGao commented 8 years ago

@thienhv295 Unfortunately, I used the server to decode the SVG but failed. Finally, I change the lib to html2canvas...It seems work to me...

evianzhow commented 7 years ago

@WingGao I just wonder why html2canvas works for you. I'm using that lib but encountered the same error: SecurityError: DOM Exception 18. Can you provide a caveat about your code?

WingGao commented 7 years ago

@EvianZhow OK, maybe you miss the option useCORS.

html2canvas(myElement, {useCORS: true}).then(function (canvas) {
    try {
        b64Data = canvas.toDataURL("image/png");
    } catch (err) {
        console.log(err)
    }
}).catch(function onRejected(error) {
});
evianzhow commented 7 years ago

@WingGao My caveat is similar to your's. But Safari raise the exception: SecurityError (DOM Exception 18): The operation is insecure.

mtmckenna commented 7 years ago

Hello! I'm getting Exception 18 in Safari too. Here's the error:

Error: SecurityError: DOM Exception 18
toDataURL
(anonymous function) — dom-to-image.js:98
promiseReactionJob

Might be related to this issue? http://stackoverflow.com/questions/33972254/svgpng-from-canvas-todataurl-throws-dom-exception-18-security-error-in-safari-9

WingGao commented 7 years ago

@EvianZhow @mtmckenna Here is my demo, I hope it can help you. https://jsfiddle.net/hkkynoyz/

MarkusSvensson commented 7 years ago

I have this problem and it is blocking my development as it is an Ionic app for iOS...

I verified @WingGao's "solution" to use another library: html2canvas - it works but I have some rendering problems with this lib and html2canvas does not seem to be maintained anymore.

Just want to contribute to prioritisation for this issue. As it works for html2canvas there 'should' be a workaround, but I don't know where to start.

bparousis commented 7 years ago

I'm having the same problem and I hope there's a solution soon.

bparousis commented 7 years ago

@pietersv I don't think that works, because it's not converting it to png. The "toDataUrl" does the png conversion, so you're skipping the png conversion step. You should just use toSvg if all you want is the svg image. The method toSvg works, since it doesn't call toDataUrl.

bparousis commented 7 years ago

I came up with a bit of a workaround. Basically, I use the toSvg method and then I take the <svg>....</svg> part and wrap it in <html><body><div>...</div></body></html>. I then pass this to webshot library (https://github.com/brenden/node-webshot), which uses phantomjs to take the html and create a screenshot of it. It works, but obviously not the ideal solution.

The issue is ultimately with the <foreignObject> tag. This causes the canvas to be marked as tainted and then Safari just doesn't allow you to do the toDataUrl call. I think this is something that needs to be fixed in the browser. In the meantime, just need workarounds, I guess.

pietersv commented 7 years ago

@digity You're right, this worked for part of the ways I used toDataURL() but not the actual PNG file. Wishful thinking. [post deleted]

bparousis commented 7 years ago

Here's some quick sample code for converting it to png using webshot library:

domtoimage.toSvg(node)
.then(function(dataUrl) {
    var svg = dataUrl.substring(dataUrl.indexOf('<svg'));
    webshot('<html><body><div>'+svg+'</div></body></html>', 'myimage.png', {siteType:'html'}, function(err) {
        // screenshot now saved to myimage.png
    });
})
.catch(function(error) {
    ...
});
kapyaar commented 7 years ago

I am facing the same issue. Even without any images, just pure text, it is throwing a Dom exception 18 error on chrome and safari iphone versions. works ok on desktop.

http://jsfiddle.net/8h13tmcj/26/

kapyaar commented 7 years ago

@tsayen I think it is the <foreignObject> tag causing the problem. Is it possible to generate the svg without this tag?

laflower commented 7 years ago

Same issue on ionic

tonystark93 commented 7 years ago

If you use foreign object in the svg and then converting it to canvas which contains foreign object will cause security error.

denis-sokolov commented 7 years ago

This is a duplicate of #27.

Rainpia commented 7 years ago

@WingGao I use this like you . but can not save image, do you have some advise ?

alanhe421 commented 7 years ago

@Rainpia @WingGao how to save pic ?

bsautel commented 7 years ago

@alanhg , see this comment in which I explain the workaround I use to make a screen shot in a Cordova application. It supports Android and iOS only but it may be extended to support additionnal browsers.

Hope it will help you!

minchangyong commented 6 years ago

who can copy once demo in there!