Skip to content

Commit

Permalink
Add corsImg option
Browse files Browse the repository at this point in the history
Merged @eachnawzw's PR](tsayen#329) by hand.
Bumped versions of Chai, ESLint, Prettier, and SemVer.
Updated control image to match new Chrome version.
  • Loading branch information
IDisposable committed Oct 2, 2023
1 parent 4d5fab9 commit c54ddf2
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 172 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,17 +195,20 @@ Are you facing a [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTTP
issue in your app? Don't worry, there are alternative solutions to this problem that you
can explore. Here are some options to consider:

1. **Use third-party services like [allOrigins](https://allorigins.win/).** With this
1. **Use the option.corsImg support by passing images** With this option, you can setup
a proxy service that will process the requests in a safe CORS context.

2. **Use third-party services like [allOrigins](https://allorigins.win/).** With this
service, you can fetch the source code or an image in base64 format from any website.
However, this method can be a bit slow.

1. **Set up your own API service.** Compared to third-party services like
3. **Set up your own API service.** Compared to third-party services like
[allOrigins](https://allorigins.win/), this method can be faster, but you'll need to
convert the image URL to base64 format. You can use the
"[image-to-base64](https://github.com/renanbastos93/image-to-base64)" package for this
purpose.

1. **Utilize
4. **Utilize
[server-side functions](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props)
features of frameworks like [Next.js](https://nextjs.org/).** This is the easiest and
most convenient method, where you can directly fetch a URL source within
Expand Down Expand Up @@ -327,7 +330,7 @@ Klimas (fixes), Edgardo Di Gesto (fixes), 樊冬 Fan Dong (fixes), Shrijan Tripa
SNDST00M (optimize), Joseph White (performance CSS), Phani Rithvij (test), David
DOLCIMASCOLO (packaging), Zee (ZM) @zm-cttae (many major updates), Joshua Walsh
@JoshuaWalsh (Firefox issues), Emre Coban @emrecoban (documentation), Nate Stuyvesant
@nstuyvesant (fixes)
@nstuyvesant (fixes), King Wang @eachmawzw (CORS image proxy)

## License

Expand Down
4 changes: 2 additions & 2 deletions dist/dom-to-image-more.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/dom-to-image-more.min.js.map

Large diffs are not rendered by default.

334 changes: 179 additions & 155 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "dom-to-image-more",
"version": "3.1.6",
"version": "3.2.0",
"description": "Generates an image from a DOM node using HTML5 canvas and SVG",
"main": "dist/dom-to-image-more.min.js",
"devDependencies": {
"chai": "^4.3.7",
"eslint": "^8.39.0",
"chai": "^4.3.10",
"eslint": "^8.50.0",
"grunt": "^1.6.1",
"grunt-cli": "^1.4.3",
"grunt-contrib-jshint": "^3.2.0",
Expand All @@ -20,8 +20,8 @@
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.2.5",
"mocha": "^10.2.0",
"prettier": "^2.8.8",
"semver": "^7.5.0"
"prettier": "^3.0.3",
"semver": "^7.5.4"
},
"scripts": {
"format": "eslint src --fix && prettier --write .",
Expand Down Expand Up @@ -61,7 +61,8 @@
"Andoni Zubimendi @AndoniZubimendi",
"Joshua Walsh @JoshuaWalsh",
"Emre Coban @emrecoban",
"Nate Stuyvesant @nstuyvesant"
"Nate Stuyvesant @nstuyvesant",
"King Wang @eachmawzw"
],
"license": "MIT",
"bugs": {
Expand Down
2 changes: 1 addition & 1 deletion spec/resources/defaultStyles/control-image

Large diffs are not rendered by default.

58 changes: 55 additions & 3 deletions src/dom-to-image-more.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
httpTimeout: 30000,
// Style computation cache tag rules (options are strict, relaxed)
styleCaching: 'strict',
// Default cors config is to request the image address directly
corsImg: undefined,
};

const domtoimage = {
Expand Down Expand Up @@ -76,6 +78,11 @@
* @param {Boolean} options.cacheBust - set to true to cache bust by appending the time to the request url
* @param {String} options.styleCaching - set to 'strict', 'relaxed' to select style caching rules
* @param {Boolean} options.copyDefaultStyles - set to false to disable use of default styles of elements
* @param {Object} options.corsImg - When the image is restricted by the server from cross-domain requests, the proxy address is passed in to get the image
* - @param {String} url - eg: https://cors-anywhere.herokuapp.com/
* - @param {Enumerator} method - get, post
* - @param {Object} headers - eg: { "Content-Type", "application/json;charset=UTF-8" }
* - @param {Object} data - post payload
* @return {Promise} - A promise that is fulfilled with a SVG image data URL
* */
function toSvg(node, options) {
Expand Down Expand Up @@ -259,6 +266,12 @@
domtoimage.impl.options.cacheBust = options.cacheBust;
}

if (typeof(options.corsImg) === 'undefined') {
domtoimage.impl.options.corsImg = defaultOptions.corsImg;
} else {
domtoimage.impl.options.corsImg = options.corsImg;
}

if (typeof options.useCredentials === 'undefined') {
domtoimage.impl.options.useCredentials = defaultOptions.useCredentials;
} else {
Expand Down Expand Up @@ -790,8 +803,38 @@
if (domtoimage.impl.options.useCredentials) {
request.withCredentials = true;
}
request.open('GET', url, true);
request.send();

if (domtoimage.impl.options.corsImg
&& url.indexOf('http') === 0
&& url.indexOf(window.location.origin) === -1) {
const method = (domtoimage.impl.options.corsImg.method || 'GET').toUpperCase() === 'POST'
? 'POST'
: 'GET';

request.open(method, (domtoimage.impl.options.corsImg.url || '').replace('#{cors}', url), true);

let isJson = false;
const headers = domtoimage.impl.options.corsImg.headers || {};
Object.keys(headers).forEach(function (key) {
if (headers[key].indexOf('application/json') !== -1) {
isJson = true;
}
request.setRequestHeader(key, headers[key]);
});

const corsData = handleJson(domtoimage.impl.options.corsImg.data || '');

Object.keys(corsData).forEach(function (key) {
if (typeof(corsData[key]) === 'string') {
corsData[key] = corsData[key].replace('#{cors}', url);
}
});

request.send(isJson ? JSON.stringify(corsData) : corsData);
} else {
request.open('GET', url, true);
request.send();
}

let placeholder;
if (domtoimage.impl.options.imagePlaceholder) {
Expand All @@ -806,7 +849,7 @@
return;
}

if (request.status !== 200) {
if (request.status >= 300) {
if (placeholder) {
resolve(placeholder);
} else {
Expand Down Expand Up @@ -835,6 +878,15 @@
}
}

function handleJson(data) {
try {
return JSON.parse(JSON.stringify(data));
} catch (e) {
fail('corsImg.data is missing or invalid');
return;
}
}

function fail(message) {
console.error(message);
resolve('');
Expand Down

0 comments on commit c54ddf2

Please sign in to comment.