The HTML crossorigin attribute
The HTML crossorigin attribute makes an element fetch with CORS, which a cross-origin server must allow with Access-Control-Allow-Origin. Cookies go only to the same origin with anonymous, use-credentials allows them cross-origin, and other values mean anonymous.
Overview
The HTML crossorigin attribute makes an element request its resource through CORS. If the server allows it, the browser then shares the cross-origin response with the page. The elements that accept it are <img>, <script>, <link>, <audio> and <video>.
The value anonymous requests CORS with credentials only for same-origin URLs, while use-credentials asks for them on every request, subject to cookie rules. An empty or unknown value means anonymous.
For a cross-origin file with anonymous, the response needs an Access-Control-Allow-Origin header of * or the page's origin. With use-credentials, a * fails, so the header must name the origin and come with Access-Control-Allow-Credentials: true.
With no attribute, most requests skip CORS, but module scripts, modulepreload links and manifest links use it anyway. An image or video from another origin taints any <canvas> it is drawn on unless it came through CORS, and reading the pixels then throws a SecurityError.
Without CORS, the HTML standard limits window.onerror on a cross-origin classic script to the text Script error. With crossorigin, the message, file and line come through.
Syntax
<script src="https://example.com/lib.js"
crossorigin="anonymous"></script>
<img src="https://example.com/photo.jpg" alt="Lake" crossorigin>
Values
| Value |
|---|
| anonymous (default when present) | use-credentials |
Example
<p><label for="value">crossorigin value</label>
<input id="value" value="anonymous" spellcheck="false"></p>
<p><label><input type="checkbox" id="omit"> Leave the attribute out</label></p>
<p id="msg" role="status"></p>
<p>Try use-credentials, a typo such as anon, an empty box or capitals.</p>
<script>
const value = document.getElementById('value');
const omit = document.getElementById('omit');
const msg = document.getElementById('msg');
const meaning = {
anonymous: 'CORS request, credentials only for the same origin.',
'use-credentials': 'CORS request that asks for credentials.'
};
function show() {
value.disabled = omit.checked;
const img = document.createElement('img');
if (!omit.checked) {
img.setAttribute('crossorigin', value.value);
}
const state = img.crossOrigin;
msg.textContent = state === null
? 'img.crossOrigin is null. No CORS request at all.'
: 'img.crossOrigin is "' + state + '". ' + meaning[state];
}
value.addEventListener('input', show);
omit.addEventListener('change', show);
show();
</script>
Best practices
- Pick
crossorigin="anonymous"for public files, and use-credentials only when the response depends on cookies. A web manifest that requires credentials is one such case, even on the same origin. - Add crossorigin to every cross-origin classic script or stylesheet that has an integrity attribute. Such a request always fails without crossorigin, because browsers don't allow integrity checks on no-cors requests.
- Send
Vary: Originwhen the server copies the request's origin into Access-Control-Allow-Origin. Any CORS setup more complicated than * or a fixed origin calls for Vary, which keeps cached responses apart. - Set
crossOriginbefore you insert a script element. Changing the attribute afterward has no direct effect on the script.























