CORS request not working in Safari

JavascriptSafariXmlhttprequestCors

Javascript Problem Overview


I am making a CORS xhr request. This works fine in chrome, however when I run in safari I get an 'Can not load ---- access not allowed by Access-control-allow-origin'. The code is exactly the same and I have set the CORS on the server. Below is my code.(has access control, but you are free to try without the accessToken)

 var water;
 var req = new XMLHttpRequest;
 req.overrideMimeType("application/json");
 req.open('GET', 'https://storage.googleapis.com/fflog/135172watersupplies_json', true);
 req.setRequestHeader('Authorization', 'Bearer ' + accessToken);
 origThis = this;
 var target = this;
 req.onload = function() {
 water = req;

 req.send(null);

After looking at the request headers I see that a OPTIONS request is made first and this is the request that is not allowed. The origin header is not included in the response in Safari, but is in chrome. What would cause this. Any help would be greatly appreciated.

UPDATE: I have tried in Safari for Windows and it works, so I'm not sure what is going on here. The mac that I am using is a remote access (Macincloud.com), but I don't think that would have anything to do with it.

Javascript Solutions


Solution 1 - Javascript

I encountered the same error when making an XHR request against a file in Amazon S3. On Safari 7 it was failing. I know you're not using Amazon S3, but I thought I'd post in case this solution helped others.

The problem was that Safari 7 set the Access-Control-Request-Headers header to "origin, x-requested-with", but my AWS CORS configuration only allowed "x-requested-with":

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
        <AllowedHeader>x-requested-with</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

I added "origin" as an allowed header and everything worked fine.

        <AllowedHeader>origin</AllowedHeader>

Note: the AllowedOrigin of * is for development purposes only. See @andes comment below for more information.

Solution 2 - Javascript

I just had a similar problem, CORS error. It would work in Firefox & Chrome but not Safari 10.

Turned out we needed to put the trailing slash on the JSON URL.

Solution 3 - Javascript

As for Amazon S3, it only worked in safari after I added more allowed headers, Content-Type and Range. One of these did the job.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
        <AllowedHeader>Origin</AllowedHeader>
        <AllowedHeader>X-Requested-With</AllowedHeader>
        <AllowedHeader>Content-Type</AllowedHeader>
        <AllowedHeader>Range</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

Solution 4 - Javascript

In my case, it was an issue for Accept-Language header. I have added Accept-Language inside Access-Control-Allow-Headers and it got resolved.

Solution 5 - Javascript

Im not sure if anyone else will have this problem but I was making a request to a URL like:

https://api.website.com/api/v1/users/auth0|5ef7502019360a7/

The | (pipe) character in the URL was causing a strange issue with Safari because it was not being URL Encoded correctly.

In my Javascript I simply replaced my old url:

const url = "https://api.website.com/api/v1/user/auth0|5ef27593603a7";

with

const url = "https://api.website.com/api/v1/user/auth0|5ef27593603a7".replace("|", "%7C");

%7C is the correct URL encoding for the | (pipe) character.

Hope this helps someone!

Solution 6 - Javascript

Set two response headers:

  1. Access-Control-Allow-Methods: '*', allow all

  2. Turns out server had Access-Control-Allow-Methods response header's value is set to *. It had to explicitly set to allow methods instead of a wildcard as it is not supported by a safari in iOS as given here in this MDN doc.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods

Solution 7 - Javascript

For CORS request you should be using your origin fflog.storage.googleapis.com. If you use common storage.googleapis.com origin, any site can access to your bucket.

have try try remove overrideMimeType? If you set mime type, it will return correctly.

I also have problem with Safari POST request, but no answer yet. GET is OK.

Solution 8 - Javascript

When I try

curl -v -X OPTIONS \
  -H 'Origin: fflog.storage.googleapis.com' \
  -H 'Access-Control-Request-Method: GET'  \
  https://storage.googleapis.com/fflog/135172watersupplies_json

I get, among other headers:

Access-Control-Allow-Origin: *

When I execute AJAX requests against https://storage.googleapis.com/fflog/135172watersupplies_json from Safari 6.0.4 on Mac OS 10.8.3 I get 403 errors, but they do all execute.

So I can only guess that you are trying to send a credentialed request for which a wildcard Access-Control-Allow-Origin is not allowed.

Solution 9 - Javascript

I had the same problem where CORS worked in Chrome, but threw an origin error in Safari. Turned out it was a Kerberos authorization issue. When I loaded the XHR URL directly in Safari, I was prompted for credentials. After entering them, I returned to the original site, and Safari no longer had the CORS error.

Solution 10 - Javascript

We had the exact same issue on Cloudfront (backed by s3 bucket) and the solutions given here did not help. The problem was with Cloudfront clipping some headers. This resolved it for us:

https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/

Putting it here just in case someone comes across this solution in future.

Solution 11 - Javascript

I had a similar problem. I had a site where the login worked from site A, upon a successful login, the user would get redirected to site B. Both site A and B load the same language file from site A. What was happening to me, was that the file got first loaded on site A (No CORS required) but when the user went to site B, Safari interpreted it had that file already, but the internal failed with a CORS error, as it had it cached from site A.

The solution is to make the server add a "Vary: Origin" header to the response so that dumb Safari knows how to properly manage the cached file.

Solution 12 - Javascript

try to remove overide mimetype.

 var
 jsonhandler=function(){var req=JSON.parse(this.response);console.log(req)},
 req=new XMLHttpRequest;
 req.open('GET','https://storage.googleapis.com/fflog/135172watersupplies_json');
 req.setRequestHeader('Authorization','Bearer '+accessToken);
 req.onload=jsonhandler;
 req.send();

Solution 13 - Javascript

Thanks for all the responses, I got this finally myself. I added 'Origin' to my responseHeaders and works fine now.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPatrick JacksonView Question on Stackoverflow
Solution 1 - JavascriptSethView Answer on Stackoverflow
Solution 2 - JavascriptWilliam MacdonaldView Answer on Stackoverflow
Solution 3 - JavascriptEdhowlerView Answer on Stackoverflow
Solution 4 - JavascriptdeenView Answer on Stackoverflow
Solution 5 - JavascriptChristian BartramView Answer on Stackoverflow
Solution 6 - Javascriptcode.rookieView Answer on Stackoverflow
Solution 7 - JavascriptKyaw TunView Answer on Stackoverflow
Solution 8 - JavascriptOld ProView Answer on Stackoverflow
Solution 9 - JavascriptSeth MooreView Answer on Stackoverflow
Solution 10 - JavascriptSarangView Answer on Stackoverflow
Solution 11 - JavascripthernvncView Answer on Stackoverflow
Solution 12 - JavascriptcoccoView Answer on Stackoverflow
Solution 13 - JavascriptPatrick JacksonView Answer on Stackoverflow