CORS не работает в Chrome

Я настроил общий доступ к ресурсам Cross-Origin на сервере (Jetty с использованием CrossOriginFilter), и он отлично работает в IE8 и Firefox. В Chrome это просто... не работает.

  $.ajax({ url : crossOriginURL,
    type : "GET",
    error : function(req, message) {
        alert(message);
    },
    dataType :  "json" } );

Вызывается функция ошибки с полезным сообщением «ошибка». Кажется, он делает запрос, но без каких-либо заголовков, которые вы ожидаете. Если URL-адрес из того же источника, он работает нормально.


person Malvolio    schedule 28.06.2010    source источник
comment
Мальволио и CuSS — один и тот же человек?   -  person Cipi    schedule 30.08.2010
comment
Нет! Конечно, нет! РЖУ НЕ МОГУ. У меня была такая же проблема сегодня утром. Мне нужно было срочно решить это, поэтому, чтобы не повторять вопрос, я получил вознаграждение за его вопрос, но, поскольку я решил его сейчас, я должен был ответить на него. Извините за мой плохой английский.   -  person cusspvz    schedule 30.08.2010


Ответы (8)


Я решил свою проблему следующим образом:

Добавьте это в свой PHP-код:

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true ");
header("Access-Control-Allow-Methods: OPTIONS, GET, POST");
header("Access-Control-Allow-Headers: Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control");

Или добавьте эти заголовки в свой ответ.

Проблема: браузеры запрашивают у сервера параметры перед вашим основным запросом, чтобы проверить, есть ли на сайте возможность разрешить общение с другим источником, а затем, если да, они выполняют ваш запрос POST или GET.

EDIT: Попробуйте это (без взлома), чтобы увидеть, получаете ли вы данные...

$.ajax({ url : crossOriginURL,
    type : "GET",
    error : function(req, message) {
        alert(message);
    },
    success : function(data) {
        alert(data);
    },
    dataType :  "text"} );
person cusspvz    schedule 30.08.2010
comment
На самом деле, что в итоге сработало для меня, так это xhr.setRequestHeader('Content-Type', 'text/plain'); - person Malvolio; 18.09.2010
comment
В этом случае вы можете опубликовать свой собственный ответ и отметить ЭТО как правильный? (У меня нет этой конкретной проблемы, но мне нравится поддерживать чистоту в списке вопросов без ответов) - person ssokolow; 19.09.2010
comment
мой ответ работает для всех браузеров. Вам не нужно запрашивать настраиваемые заголовки, потому что кто ограничивает или нет страницу, так это сервер и движок браузера... если вы получали пустой ответ, вероятно, это был неверный тип данных на ajax, это происходит потому, что вы не выбрали правильный тип данных. Прочтите о dataType в api.jquery.com/jQuery.ajax . в массив параметров ajax поместите {dataType: text} - person cusspvz; 21.09.2010
comment
Решение установить простой тип контента у меня не сработало (я получаю сообщение об ошибке, указывающее, что я не могу установить это в запросе). И я не пишу свой собственный серверный сервис, я использую другой онлайн (твиттер). Есть ли другое решение, использующее только JavaScript? Я также попытался установить источник на что-то конкретное, используя ту же технику, что и выше (установка заголовка запроса), но получил ошибку. Мой код отлично работает в Safari, но не работает в Chrome, хотя все указывает на то, что Chrome поддерживает CORS. - person Elisabeth; 30.05.2011
comment
у тебя есть доступ к серверу? проверить jsonp - person cusspvz; 04.06.2011
comment
Я не могу заставить CORS работать в Chrome. У меня есть контроль над сервером, я возвращаю запрошенный метод, заголовки и конкретный источник, которые я получаю по запросу, и браузер по-прежнему не может отправить запрос XHR. Если у кого-то это работает с Javascript, не могли бы вы опубликовать сообщение OPTIONS и возвращенный ответ в качестве примера, пожалуйста? - person Steve Hibbert; 28.01.2013
comment
@CuSS Отличный ответ! Я уже включил вышеупомянутые заголовки на стороне сервера. По-прежнему не удалось получить заголовки через вызовы AJAX. Затем я прочитал о 'Problem: ' части, которую вы упомянули в ответе, и это помогло мне. Я добавлял header("Access-Control-Allow-Origin: *"); в качестве второго последнего заголовка. Когда я изменил порядок (сохранил его как первый заголовок), это сработало для меня. Также я установил только type: 'GET' в настройках. Сохранение dataType: 'jsonp' не возвращает мне заголовок, оно возвращает мне только ответ/данные. Это может помочь другим, которые сталкиваются с подобными проблемами. Еще раз спасибо - person Anish Nair; 03.12.2013
comment
@CuSS Access-Control-Allow-Origin: * и Access-Control-Allow-Credentials: true являются взаимоисключающими! Соответствующие пользовательские агенты (браузеры) будут отклонять (ошибка) ответ на любой запрос CORS с учетными данными, если сервер отвечает Access-Control-Allow-Origin: *; заголовок Access-Control-Allow-Credentials даже не будет проверяться, поскольку он не разрешен с разрешенными источниками с подстановочными знаками. См. документацию Mozilla. - person CBHacking; 29.03.2017
comment
@CBHacking, это ответ от 2010 года. 6 лет назад CORS был только у Chrome. - person cusspvz; 30.03.2017
comment
... и я почти уверен, что ACAO: * и ACAC: true тогда тоже были несовместимы, документы Mozilla были просто первыми, к которым я пришел. (FWIW, IE8 имел частичную поддержку CORS еще в 2009 году, но запросы с учетными данными все равно не поддерживались.) - person CBHacking; 30.03.2017
comment
У меня похожая проблема, мое приложение создано с использованием Angular 7. Я делаю вызов ajax на сервер BPMS, который отлично работает в IE, но у меня есть ошибка CORS в Chrome. Однако, когда я копирую URL-адрес ajax в браузер Chrome, у меня есть все данные. Кто-нибудь может помочь? - person David Sagang; 18.08.2020

что, наконец, сработало для меня, так это xhr.setRequestHeader('Content-Type', 'text/plain');

EDIT: сервер должен добавить Access-Control-Allow-Headers: Content-Type, чтобы избежать этой проблемы.

Я возвращаюсь к своему собственному вопросу десять лет спустя. Я не знаю, хорошо это или ужасно.

person Malvolio    schedule 29.08.2011
comment
Чтобы объяснить это более подробно, использование необработанных данных позволяет избежать предварительной проверки, которая чаще встречается в CORS. Поскольку нет предварительной проверки, нет и проверок управления доступом, что позволяет избежать всей проблемы. +1 - person Richard; 25.09.2013
comment
@Richard Это только наполовину правильно. Это позволяет избежать предварительной проверки, но даже необработанные запросы CORS могут привести к ошибкам (например, если нет соответствующего заголовка ответа Access-Control-Allow-Origin: .... Причина, по которой это работает, на самом деле очень проста: text/plain — это один из очень немногих типов контента, которые разрешены без явный Access-Control-Allow-Headers: Content-Type заголовок ответа. json (или application/json требует разрешения явного заголовка. - person CBHacking; 29.03.2017
comment
@CBHacking - семь чертовых лет спустя кто-то дает правильный ответ. Не знаю, хорошо это или плохо, что семь лет спустя я проверяю сайт в течение двух часов. В любом случае, почему бы вам не ответить, и я могу принять его? - person Malvolio; 30.03.2017

Похоже, что оригинальный постер, возможно, решил свою проблему, но для тех, у кого такая же проблема, как у комментатора Элизабет, я полагаю, что проблема может заключаться в том, что Chrome отказывается устанавливать заголовок Origin для запроса CORS, если вы выполняете запрос из локальный файл. Он даже не позволит вам явно переопределить заголовок Origin. Это приводит к тому, что сервер видит «Происхождение: ноль», что в большинстве случаев приводит к ошибке 403. Firefox, по-видимому, не имеет такого ограничения, как я обнаружил после долгих выдергиваний.

Если в этом случае вам абсолютно необходимо использовать Chrome, вы можете решить проблему, запустив веб-сервер локально и всегда обращаясь к вашему файлу через http: вместо file:.

person Eric    schedule 31.10.2012
comment
Менее навязчивое (хотя и временное) решение можно получить, запустив Chrome с отключенной защитой от разных источников: path/to/chrome --disable-web-security. Предупреждение: если вы продолжите использовать незащищенный Chrome для обычного просмотра, либо ничего не произойдет, либо ваш банковский счет будет взломан, так что удачи вам в этом. - person Malvolio; 31.10.2012
comment
Это действительно спасло мой день! Как только я разместил исходный запрос за простым веб-сервером, все было в порядке. - person Samuel Ellis; 22.01.2017

Убедитесь, что вы не настроили сервер как на разрешение учетных данных, так и на то, что заголовок разрешения источника имеет значение *. Как показано ниже:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Если ваш сервер возвращает эти значения для этих заголовков, это не сработает. Если вы установите Access-Control-Allow-Credentials в true, то вы не сможете использовать * как значение заголовка Access-Control-Allow-Origin. Ниже приведена выдержка из веб-документов MDN для заголовка (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin):

For requests without credentials, the literal value "*" can be specified, as a wildcard; 
the value tells browsers to allow requesting code from any origin to access the resource. 
Attempting to use the wildcard with credentials will result in an error.

Если это так, просто установите Access-Control-Allow-Credentials на false.

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: false

использованная литература

person king    schedule 10.05.2019

Когда я обновил хром, я столкнулся с проблемой, я решил новую версию Google Extension «Access-Control-Allow-Credentials». если это старая версия, вам не нужно будет работать с новой версией Google Chrome

https://chrome.google.com/webstore/detail/access-control-allow-cred/hmcjjmkppmkpobeokkhgkecjlaobjldi?hl=en

person Siddhartha Mukherjee    schedule 20.04.2019

На самом деле у нас есть два домена: один для информационной панели dashboard.app.com, а другой — для общедоступного веб-сайта app.com. Запрос исходил с общедоступного веб-сайта, а маршрутизация PHP перенаправляла на домен панели инструментов, поэтому мы получили ошибку. Решение состояло в том, чтобы оставить все запросы в одном домене без перенаправлений.

person Pedro Góes    schedule 21.05.2021

В моем случае это localhost:8001 (внешний интерфейс), который пытается вызвать API-интерфейсы на localhost:7001 (на server.js в качестве сервера Node). Даже у меня был установлен и включен плагин CORS в Chrome, но политика CORS отклоняла их как предварительные проверки.

Мне потребовалось больше половины дня, чтобы окончательно решить проблему. Вот "глупые" шаги, хотите верьте, хотите нет:

я. Выключите плагин CORS, перезагрузите приложение, в это время вы все равно должны получать правильные ошибки.

II. Включите его снова, перезагрузите приложение, если API работают успешно, остановитесь на этом, нет необходимости переходить к iii.

III. Однако, если вы по-прежнему получаете отказ CORS, удалите Chrome и установите последнюю версию Chrome.

IV. В новом Chrome ранее установленный плагин CORS все еще должен быть там, но со статусом OFF.

v. Перезагрузите страницу, вы должны получить правильные сообщения об отклонении CORS на консоли.

ви. Включите его обратно, перезагрузите страницу, ошибки должны исчезнуть.

Никаких дальнейших идей, если описанные выше шаги все еще не работают в вашем случае.

Я также пробовал следующее на server.js (Node) и все еще не работает, поэтому не стоит пытаться:

var app = express();
var cors = require('cors'); // Already done “npm i cors --save-dev”
app.options('*', cors());
person Daniel C. Deng    schedule 11.10.2017

CORS будет работать в хроме. Просто используйте Chrome в безопасном режиме, то есть отключите настройки безопасности. Погуглите об этом, или вы даже можете начать из командной строки.

person pranavbapat    schedule 27.05.2013
comment
Это не очень хорошее решение, потому что (а) оно по своей сути не-безопасно, (б) оно требует, чтобы пользователь остановил Chrome, а затем перезапустил его, прежде чем мой сайт заработает, и (в) мне нужно было решение три года назад! - person Malvolio; 28.05.2013