To ensure your code works properly (after resolving syntax errors), it is essential to manage the crossOrigin
attribute before reaching the next microtask checkpoint. This means that the setting must be done synchronously, not in an async script or event handler.
Although most browsers adhere to this rule, some may load cached images synchronously. To prevent this issue, you can simply reset the src
to the same value, forcing the browser to load the resource with the correct headers.
$('img').each(function() {
var $img = $(this);
$img.attr({
crossorigin: "anonymous",
src: this.src
});
});
// check if loaded with proper headers
$(window).on("load", () => {
const canvas = document.createElement("canvas");
canvas.getContext("2d").drawImage($('img')[0], 0, 0);
console.log('cross-origin enabled', !!canvas.toDataURL());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img width="50%" src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png">
If I were in your position, I would double-check the timing for this action. The ideal solution is to set the attribute from the beginning:
// check if loaded with proper headers
window.onload = () => {
const canvas = document.createElement("canvas");
canvas.getContext("2d").drawImage( document.querySelector('img'), 0, 0);
console.log('cross-origin enabled', !!canvas.toDataURL());
};
<img crossorigin="anonymous" width="50%" src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png">
It's worth noting that the image in question is served by Amazon S3 with a Vary: Origin
header only for cross-origin requests. This setup causes Chrome to still use the cached version, even when the crossOrigin
attribute is specified. For further details, refer to this Q/A thread.
In such scenarios, the best workaround is always setting the crossOrigin
attribute.