CORS-запрос не работает в Safari

Я делаю запрос CORS xhr. Это хорошо работает в Chrome, однако, когда я запускаю в Safari, я получаю "Не могу загрузить ---- доступ запрещен Access-control-allow-origin". Код точно такой же, и я установил CORS на сервере. Ниже мой код.(Имеет контроль доступа, но вы можете попробовать без 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);

Посмотрев заголовки запроса, я вижу, что сначала выполняется запрос OPTIONS, и этот запрос запрещен. Заголовок источника не включен в ответ в Safari, но в Chrome. Что бы вызвать это. Любая помощь будет принята с благодарностью.

ОБНОВЛЕНИЕ: я пробовал в Safari для Windows, и он работает, поэтому я не уверен, что здесь происходит. Макинтош, которым я пользуюсь - это удаленный доступ (Macincloud.com), но я не думаю, что это как-то связано с этим.

14 ответов

Решение

Спасибо за все ответы, я наконец-то получил это сам. Я добавил "Origin" в мои responseHeaders и теперь работает нормально.

Я столкнулся с той же ошибкой при выполнении запроса XHR для файла в Amazon S3. На Safari 7 это не удавалось. Я знаю, что вы не используете Amazon S3, но я решил опубликовать, если это решение поможет другим.

Проблема заключалась в том, что Safari 7 установил заголовок Access-Control-Request-Headers на "origin, x-required-with", но моя конфигурация AWS CORS допускала только "x-required-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>

Я добавил "origin" в качестве разрешенного заголовка, и все работало нормально.

        <AllowedHeader>origin</AllowedHeader>

Примечание: разрешенный источник * только для целей разработки. Смотрите комментарий @andes ниже для получения дополнительной информации.

У меня просто была похожая проблема, ошибка CORS. Это будет работать в Firefox и Chrome, но не в Safari 10.

Оказалось, что нам нужно добавить косую черту в JSON URL.

Я не уверен, будет ли у кого-нибудь еще эта проблема, но я делал запрос по URL-адресу, например:

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

В | Символ (вертикальная черта) в URL-адресе вызывал странную проблему с Safari, потому что URL-адрес кодировался неправильно.

В своем Javascript я просто заменил свой старый URL:

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

с

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

%7C правильная кодировка URL для | (трубка) персонаж.

Надеюсь, это кому-то поможет!

У меня была аналогичная проблема. У меня был сайт, на котором вход работал с сайта A, после успешного входа пользователь перенаправлялся на сайт B. Оба сайта A и B загружали один и тот же языковой файл с сайта A. Что происходило со мной, так это то, что файл был сначала загружен на сайт A (CORS не требуется), но когда пользователь перешел на сайт B, Safari интерпретировал, что у него уже есть этот файл, но внутренний отказал с ошибкой CORS, так как он был кэширован с сайта A.

Решение состоит в том, чтобы заставить сервер добавлять в ответ заголовок «Vary: Origin», чтобы тупой Safari знал, как правильно управлять кэшированным файлом.

Установите два заголовка ответа:

  1. Access-Control-Allow-Methods: '*', разрешить все

  2. Оказывается, на сервере значение заголовка ответа Access-Control-Allow-Methods установлено на *. Он должен был явно разрешить методы вместо подстановочного знака, поскольку он не поддерживается сафари в iOS, как указано здесь в этом документе MDN.

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

В моем случае это была проблема с заголовком Accept-Langauge. я добавил Accept-Language внутри Access-Control-Allow-Headers и это было решено.

Что касается Amazon S3, он работал только в сафари после того, как я добавил больше разрешенных заголовков, Content-Type и Range. Один из них сделал работу.

<?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>

У меня была такая же проблема, когда CORS работал в Chrome, но в Safari вызвала ошибку происхождения. Оказалось, что это проблема авторизации Kerberos. Когда я загружал URL-адрес XHR непосредственно в Safari, у меня запрашивали учетные данные. После ввода их я вернулся на исходный сайт, и в Safari больше не было ошибки CORS.

У нас была такая же проблема на Cloudfront(при поддержке ведра s3), и приведенные здесь решения не помогли. Проблема заключалась в том, что Cloudfront обрезал некоторые заголовки. Это решило проблему для нас:

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

Поместите его сюда на случай, если в будущем кто-то столкнется с этим решением.

Для запроса CORS вы должны использовать свое происхождение fflog.storage.googleapis.com, Если вы используете общий storage.googleapis.com Происхождение, любой сайт может получить доступ к вашему ведру.

есть попытаться попытаться удалить overrideMimeType? Если вы установите тип MIME, он вернется правильно.

У меня также есть проблема с Safari POST-запросом, но пока нет ответа. GET в порядке.

Когда я пытаюсь

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

Я получаю, среди других заголовков:

Access-Control-Allow-Origin: *

Когда я выполняю запросы AJAX против https://storage.googleapis.com/fflog/135172watersupplies_json из Safari 6.0.4 в Mac OS 10.8.3 я получаю 403 ошибки, но все они выполняются.

Таким образом, я могу только догадываться, что вы пытаетесь отправить запрос с полномочиями, для которого подстановочный знак Access-Control-Allow-Origin не допускается.

Попробуй удалить оверид миметипа.

 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();

Когда я запрашиваю ваш URL, я получаю следующие заголовки Access-Control:

Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Authorization, Cache-Control, Content-Length, Date, Expires, Server, Transfer-Encoding, x-goog-meta-foo1

Я подозреваю, что это как-то связано с вашими заголовками Access-Control - либо вы что-то упускаете, либо слишком конкретны.

Учитывая, что вы на самом деле отправляете пользовательский заголовок, вы можете попробовать:

Access-Control-Allow-Headers: *

Вы также можете увидеть, если оставить Access-Control-Expose-Headers имеет значение.

Кроме того, было бы полезно увидеть фактические заголовки запроса / ответа.

Другие вопросы по тегам