admin管理员组

文章数量:1315258

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", "", 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 &ecirc;tes ici</pre></strong></body></html>

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.", 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 &ecirc;tes ici</pre></strong></body></html>
Share Improve this question edited Nov 15, 2014 at 20:41 asked Nov 15, 2014 at 15:14 user347284user347284 5
  • I cannot reproduce this behavior running from localhost on safari 7.0.1. What domain are you executing your request from? – Jonathan Crowe Commented Nov 20, 2014 at 20:37
  • I can't reproduce it either from localhost but if I right-click the file to open it with Safari it does load the page's content. If I do that with Chrome or Firefox, it doesn't. Is this simply a Safari peculiarity? – user347284 Commented Nov 21, 2014 at 1:54
  • Can you share a screen shot of the network panel in your safari browser? Also can you see if there are any console messages from the browser? Also just including the CORS browser patibility reference to aid with answering. caniuse./#feat=cors – Jerome Anthony Commented Nov 23, 2014 at 8:37
  • There is no console message besides the result of the query. Here's the requested screenshot: i59.tinypic./280p1l1.png – user347284 Commented Nov 23, 2014 at 18:29
  • XMLHttpRequest cannot load perdu.. Origin file:// is not allowed by Access-Control-Allow-Origin. this is safari result – ProllyGeek Commented Nov 24, 2014 at 18:17
Add a ment  | 

2 Answers 2

Reset to default 5 +50

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 ment 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.", 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.
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.
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.
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.

本文标签: javascriptCORS request working with SafariStack Overflow