6

I am having some odd issues with some external scripts on my website. I finally got it down to this snippet.

<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js" onload="console.log('conversion')"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" onload="console.log('jquery')"></script>

Loading this in firefox has just the second script loading, while with chrome, both load. This is on OSX with the latest browsers.

Now if I add the crossorigin attribute to both scripts, then it stops working in chrome with this error Script from origin 'http://www.googleadservices.com' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.example.com:3000' is therefore not allowed access.

The scripts now are

<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js" onload="console.log('12123')" crossorigin async></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" onload="console.log('123')" async crossorigin></script>

I was struck by this difference in behaviour. Is this due to firefox being more strict than CHrome? Is this a setting I set somewhere? Or is this a bug on Firefox/Chrome's side?

Also, should I talk to the vendor to get their js setup for CORS? What struck me was that google was failing, but I have another resource breaking as well.

By right MDN claims that script tags are not limited by the same origin policy.

Karthik T
  • 31,456
  • 5
  • 68
  • 87
  • try swapping them around (jquery first) – ericosg Feb 12 '16 at 09:14
  • @ericosg This is an artificial example, these 2 lines arent present in my code, My code uses just the first one as an external resourse I believe. After I found the disparity between FF and chrome, I found the second one from stack overflow sourcecode :P – Karthik T Feb 12 '16 at 09:17
  • Please refer to the below article: [http://stackoverflow.com/questions/10636611/how-does-access-control-allow-origin-header-work](http://stackoverflow.com/questions/10636611/how-does-access-control-allow-origin-header-work) – Rovi Feb 16 '16 at 12:28
  • Have a look at this response: http://stackoverflow.com/a/32738110/7966 – Sarhanis Feb 22 '16 at 05:09

2 Answers2

5

The Cross-Origin Resource Sharing policy exists to prevent Site A from taking scripts or data hosted on Site B, and including them on it's own site. If Site A wants to allow Site B to access those scripts, they can set an Access-Control-Allow-Origin header. This header means that Site B can allow specified hosts to include the scripts on their site.

Site B needs to enable the Access-Control-Allow-Origin header on their server, to allow you to access it. For a single url, set the following header:

Access-Control-Allow-Origin: http://yoursite.com

Edit

The crossorigin attribute does not allow different origins to use the script, it just handles the window.onerror differently. From the MDN Page:

Normal script elements pass minimal information to the window.onerror for scripts which do not pass the standard CORS checks. To allow error logging for sites which use a separate domain for static media, several browsers have enabled the crossorigin attribute for scripts using the same definition as the standard img crossorigin attribute. Efforts to standardize this attribute are underway on the WHATWG mailing list.

IeuanG
  • 504
  • 5
  • 13
  • This doesnt tell me either why firefox is working differently or help me understand the difference between specifying `crossorigin` on the tag vs not.. And [MDN](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Cross-origin_network_access) says that `script` tag can be used cross origin – Karthik T Feb 22 '16 at 04:47
  • Firefox most likely has strict cross origin policies, and may behave differently to chrome as such. – IeuanG Feb 22 '16 at 07:23
  • While using the `crossorigin=""` only affects error handling, if you specify it the server on the other side must opt into CORS. – Anne Feb 28 '16 at 13:27
  • FWIW, this is standardized already: https://html.spec.whatwg.org/multipage/scripting.html#the-script-element. – Anne Feb 28 '16 at 13:27
2

If the script attribute is present, the HTTP header will need to be also present. Essentially that's what works for both browsers.

The script tag crossorigin attribute isn't a standard yet but the CORS implementations should be. See here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin

I believe what you're seeing is a bug in the WebKit CORS implementation. There was a bug filed a while ago looking at a similar issue and I don't think they followed up. See WebKit bug 107389

When looking at the headers for each you can see that googleadservices doesn't send any CORS information which should cause Chrome to not load the resource. This is what Firefox does, however Chrome seems to require the attribute to properly block.

curl -i "https://www.googleadservices.com/pagead/conversion.js"

HTTP/1.1 200 OK
P3P: policyref="https://www.googleadservices.com/pagead/p3p.xml", CP="NOI DEV PSA PSD IVA IVD OTP OUR OTR IND OTC"
Content-Type: text/javascript; charset=ISO-8859-1
Date: Mon, 22 Feb 2016 05:10:29 GMT
Expires: Mon, 22 Feb 2016 05:10:29 GMT
Cache-Control: private, max-age=86400
X-Content-Type-Options: nosniff
Content-Disposition: attachment; filename="f.txt"
Server: cafe
X-XSS-Protection: 1; mode=block
Alternate-Protocol: 443:quic,p=1
Alt-Svc: quic=":443"; ma=2592000; v="30,29,28,27,26,25"
Accept-Ranges: none
Vary: Accept-Encoding
Transfer-Encoding: chunked

curl -i https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js

HTTP/1.1 200 OK
Vary: Accept-Encoding
Content-Type: text/javascript; charset=UTF-8
Access-Control-Allow-Origin: *
Timing-Allow-Origin: *
Date: Tue, 16 Feb 2016 17:29:02 GMT
Expires: Wed, 15 Feb 2017 17:29:02 GMT
Last-Modified: Fri, 16 Oct 2015 18:27:31 GMT
X-Content-Type-Options: nosniff
Server: sffe
X-XSS-Protection: 1; mode=block
Cache-Control: public, max-age=31536000, stale-while-revalidate=2592000
Age: 475251
Alternate-Protocol: 443:quic,p=1
Alt-Svc: quic=":443"; ma=2592000; v="30,29,28,27,26,25"
Accept-Ranges: none
Transfer-Encoding: chunked
Bryan Clark
  • 2,542
  • 1
  • 15
  • 19
  • Finally an answer with some flesh to it.. Are you saying that all cdn style services will need to provide the header? What about my link to MDN which says that scripts can be embedded without the CORS handling? If cross origin is by default and it is chrome which is broken, then what is the point of the attribute at all? The bug you referenced is a bug with the attribute but you say that the issue is with chrome when the attribute isnt provided, can you find a bug for that? – Karthik T Feb 22 '16 at 07:30