25

I’d like to include some preconnect resource hints on my site so that browsers can (for example) connect to the jQuery CDN before they actually see the script tag that invokes the CDN. I’m not sure whether I should include the “crossorigin” attribute or what its value should be. The spec says, in part,

To initiate a preconnect, the user agent must run these steps:

[…]

  1. Let corsAttributeState be the current state of the element's crossorigin content attribute.
  2. Let credentials be a boolean value set to true.
  3. If corsAttributeState is Anonymous and origin is not equal to current Document's origin, set credentials to false.
  4. Attempt to obtain connection with origin and credentials.

I don’t know how to interpret this algorithm. If I’m preconnecting to a CDN, which will let anyone download its content without any sort of credentials, what value should I use for the “crossorigin” attribute?

1

4 Answers 4

11

All the answers so far seem either simplified, incomplete or partially wrong (topic is complex, things are confusingly named and not well documented!), so here's my understanding:

To be able to reuse the connection created by <link rel=preconnect>, things depend on what kind of content you want to fetch, from where, whether the request will send browser credentials (which can be established by the browser explicitly or implicitly):

The request is same-origin (example.com requests subresource from example.com)

There's no need for preconnect at all in the first place; the browser keeps the connection open after loading the page for quite a while. If there are multiple connections to be opened, the browser decides by itself if and how many to open (depending if server announces HTTP/2 support in TLS handshake, browser settings etc.)

to be checked: what if same-origin request has crossorigin attribute: is it used or ignored?

The request is cross-origin (example.com requests subresource from another.com)

  • if the actual request has crossorigin attribute explicitly set in HTML (crossOrigin in JS - case is important), the preconnect must also have it, with same value (perhaps except in cases where it doesn't make sense and crossorigin is ignored -- not fully clear for me yet)
  • else, if request if for <script type=module>: to be checked
  • else, if request is and "old school" request for <img>, <style type=stylesheet>, <iframe>, classic <script> etc. (initiated via HTML or JS) without crossorigin explicitly specified, then the preconnect MUST NOT have crossorigin attribute set.
  • else, if request is a cross-origin font request, preconnect must have crossorigin=anonymous
  • else, if request is a cross-origin fetch or XHR:
    • if it is done in credentialed mode (i.e. cookies are attached or HTTP basic auth is used; in case of fetch, this means credentials !== omit; in case of XHR: withCredentials === true): preconnect must have crossorigin=use-credentials
    • if it is not in credentialed mode: preconnect must have crossorigin=anonymous

For the last case (fetch/XHR), go to network panel in Chrome/Firefox devtools, right click a request, and choose copy as fetch from a dropdown. This will create a snippet of JS, which will tell you if that request is CORS-enabled ("mode"=="cors") and credentialed ("credentials"=="include"|"same-origin").

Note however the trick above doesn't work correctly for non-XHR/fetch requests, because for example fetch and <img> use different algorithms to establish connection, as explained before.

Finally, in HTML, <link ...crossorigin> === <link ...crossorigin=anonymous>.

Additional notes and links:

7

I was searching for the same thing and I found this

It states here that if you don't use cross origin attribute the user agent just does the dns lookup but doesn't establish connection with the particular domain. So crossorigin attribute is needed if you have to preconnect to cross domain, like this:

<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>

Also if you want to send some credentials to that particular cross domain you can set the value to crossorigin as crossorigin = use-credentials otherwise I think the default value is anonymous.

1
  • 1
    This is half-true. If CORS is used (as it is with fonts), only the DNS lookup will be used with the font request. (The connection still happens, but it's not shown in the waterfall chart because a separate connection must be opened for the CORS request.) If you're fetching a script, using crossorigin will similarly waste a connection, because a new connection must be opened that doesn't use CORS. Apr 30, 2019 at 20:28
3

It depends on two things:

  1. The type of assets to be downloaded (which determines whether CORS will be used)
  2. Whether the target server uses credentials for CORS connections

For jQuery, you would not use crossorigin. Scripts are not among the types of resources browsers use CORS to download.

Fonts, on the other hand, use CORS.

  • If the page will only fetch resources that use CORS, include the crossorigin attribute.
  • If the page will only fetch resources that don't use CORS, omit crossorigin. If
  • If the page will fetch both kinds of resources, you may need two resource hints. (Full disclosure, the link is to my personal site. :-)) Someone pointed out that you might not need two hints for HTTP/2. I haven't had time to test.

Here's the Stack Overflow post where I encountered the same issue.

I haven't dived into when CORS credentials are necessary. I haven't seen an example where they're needed, so chances are you're safe with crossorigin (i.e. `crossorigin="anonymous").

2

So far i understand the usage of crossorigin, specially in terms of its values anonymous and use-credentials, you should use crossorigin="use-credentials"in case:

  • you use assets, like images or videos, which have a crossorigin attribute
  • you plan to carry cookies, HTTP authentication, and client-side SSL certificates between origins, based on the user agent's previous interactions with the origin.

Additionally to the documentation cited by you i got this and that. But indeed the documentation is misleading and contains misspelling: the first calls it use-credentials, the second - user-credentials.

Anyway, in my understanding:

  • no crossorigin at all equals crossorigin="anonymous"
  • crossorigin equals crossorigin="use-credentials"

Maybe somebody would correct me.

PS: The current version of Mozilla page to the subject means:

An invalid keyword and an empty string will be handled as the anonymous keyword.

Means: no crossorigin at all, crossorigin or crossorigin="use_credentials" are all handled as crossorigin="anonymous".

1
  • 5
    I believe, as mentioned in MDN, By default (that is, when the attribute is not specified), CORS is not used at all. Also, setting only crossorigin is equal to crossorigin="anonymous". Mar 22, 2019 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.