'React dom-to-image error when there is an external image link in the dom

I wanted to save a dom as an image, I used dom-to-image it works when there is no external image link in the dom

dom-to-image

enter image description here

This Works

enter image description here

It saved the image

enter image description here

But when i add an image tag with an external link to it

enter image description here

It throws an error

enter image description here



Solution 1:[1]

Yes and that is all right as the library trying to fetch those images.

And the browser do not allow fetch operation when CORs origin is blocked.

So there is really a little you could do about that.

So this is how you could solve this. Create a nodejs express and route the image uri to you express api eg http://localhost:5000/getimage?url=https://xxx.png and use fetch to download and return this image as file.

Here is an example I did on my API to download images:

app.get("/api/imageHandler", async (reg, res) => {
    try {

        const imgUrl = reg.query.url.replace(/.jpg/gmi, "");
        const parserName = client.descriptString(decodeURIComponent(reg.query.source));
        const title = client.descriptString(decodeURIComponent(reg.query.title)).replace(/[^a-zA-Z| ]/gmi, "");
        const finaleSize = reg.query.finaleSize;
        if (!parserName || parserName.length <= 2) {
            res.statusCode = 304
            res.end()
        }

        var url = decodeURIComponent(client.descriptString(decodeURIComponent(imgUrl))); // decrypt the image url
        var u = new URL.URL(url);
        var filename = title + ".jpeg";
        var imageFolder = './images/' + parserName;
        var file = imageFolder + "/" + filename;
        if (!fs.existsSync(imageFolder))
            fs.mkdirSync(imageFolder)

        const searchFolders = () => {
            const folders = ["folder1", "folder2", parserName]
            for (var folder of folders) {
                var imgFolder = './images/' + folder;
                if (!fs.existsSync(imgFolder))
                    continue;
                var dr = fs.readdirSync(imgFolder);
                var f = dr.find(x => x.toLowerCase().indexOf(title.toLowerCase()) !== -1);
                if (f) {
                    file = imgFolder + "/" + f;
                    filename = f;
                    imageFolder = imgFolder;
                    break;
                }
            }
        }

        if (reg.fresh || res.getHeader("last-modified") != undefined) {
            console.log("isfress")
            res.statusCode = 304;
            return
        }

        searchFolders();
        if (fs.existsSync(file)) {
            var size = undefined
            if (finaleSize == "0" || (size = imageSize(file)).height > 100) {
                res.sendFile(filename, { root: imageFolder });
                return;
            } else fs.unlinkSync(file);
        }


        let headers = {
            'Content-Type': 'image/jpeg',
            referer: u.host,
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'
        };

        if (!url || url.length <= 3) {
            res.statusCode = 304
            res.end()
            return;
        }

        res.setHeader("age", "345600");
        res.setHeader("Accept-Ranges", "bytes");
        res.setHeader('Max-Age', "345600"); // How many bytes we're going to send
        res.setHeader('Cache-Control', 'public, max-age=345600'); // 4 days
        res.setHeader('Expires', new Date(Date.now() + 345600000).toUTCString());
        res.setHeader('Content-Type', 'image/jpeg');
        res.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
        res.setHeader('Last-Modified', "Mon, 03 Jan 2011 17:45:57 GMT");
        res.setHeader('If-Modified-Since', "Mon, 03 Jan 2011 17:45:57 GMT");

        addCore(res, true);
        fs.stat(file, function (err, stats) {
            if (err) {
                // If the image does not exist on the file system
                // Pipe the image to a file and the response object
                fetch(url, { headers: headers, method: 'GET' }).then(x => {
                    // Create a write stream to the file system
                    var stream = new Stream.PassThrough().pipe(fs.createWriteStream(file));
                    x.body.pipe(res);
                    x.body.pipe(stream);

                }).catch(e => {
                    if (fs.existsSync(file))
                        fs.unlink(file);
                    console.log("ImageHandler.Error", e, reg.query.url, imgUrl, "url:", url);
                })


            }
            else {
                console.log("imageHandler.error", err)
                fs.createReadStream(file).pipe(res);
            }
        })

    } catch (e) {
        console.log("ImageHandler.Error", e, reg.query.url);
        res.statusCode = (403);
        //res.end("not found")
    }
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 halfer