I understand why the following snippet doesn't work in Firefox and in Chrome: we're making an AJAX request to another domain.
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.perdu.com", true);
xhr.addEventListener("load", function() { console.debug(xhr.responseText); }, false);
xhr.send(null);
But then why does Safari output this? This is the actual content of the page. I have Safari 7.1.
<html><head><title>Vous Etes Perdu ?</title></head><body><h1>Perdu sur l'Internet ?</h1><h2>Pas de panique, on va vous aider</h2><strong><pre> * <----- vous êtes ici</pre></strong></body></html>
Update
It turns out that Safari behaves differently when loading from a server or from a file system.
The original answer below tests the CORS functionality with a file:///
scheme. Safari lets users bypass CORS on that scheme.
As Jonathan Crowe pointed out on localhost
, so with the http://
scheme, Safari blocks the response, same as Firefox and Chrome.
So there is no bug on this one. As for the behaviour on the file system, I guess we can call it a feature, or a convenience (thinking about quick local tests)?
Note: This update relies on an additional, simple test to serve the HTML snippet below from an HTTP server. Nothing fancy, and Safari just behaves as the others.
Original answer
I could reproduce the problem. It might be a bug in Safari 7.1, and here is what I found toward that temporary conclusion.
- Not reproducible on Safari 7.0.1 (see comment by Jonathan Crowe).
- Two main differences:
- Safari is the only browser that does NOT set the
Origin
header. Others set it to null
.
- The WebKit versions differ in Safari and Chrome.
- No bug report related to CORS on Apple's tracking system.
Also, this version of Safari allows setting the Origin
header on the XMLHttpRequest
object (Chrome does not):
xhr.setRequestHeader("Origin", null);
Setting the header to null
to get closer to the other browsers does not change the result: Safari 7.1 still allows the response to get through to the requester.
I could not make sure this is a bug in Safari 7.1, but it seems to be its behaviour right now.
Some details below.
Test page and code
<html>
<script>
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.perdu.com", true);
xhr.addEventListener("load", function() { console.debug(xhr.responseText); }, false);
xhr.send(null);
</script>
</html>
Tested versions
- Safari 7.1 (9537.85.10.17.1)
- Firefox 33.1
- Chrome 38.0.2125.122
(All on Mac OS X 10.9.5)
Firefox request dump
GET / HTTP/1.1
Host: www.perdu.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:33.0) Gecko/20100101 Firefox/33.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: null
Connection: keep-alive
Chrome request dump
GET / HTTP/1.1
Host: www.perdu.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36
Origin: null
Accept: */*
DNT: 1
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,fr;q=0.6,ja;q=0.4,pt;q=0.2
Safari request dump
GET / HTTP/1.1
Host: www.perdu.com
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10
Accept-Language: en-us
DNT: 1
Connection: keep-alive
Note
I am currently testing edge cases with CORS over a range of browsers for a web API. If a bug gets confirmed, it shouldn't be too much of a problem---provided the API security is serious enough (as CORS does not secure the server) !
Update
I have asked Apple if they can confirm on their feedback site.
You probably have the 'Disable Local File Restrictions' option enabled in the Develop menu. This will allow CORS requests to go through.