JQuery, CORS, JSON (без заполнения) и проблемы аутентификации
У меня есть два домена. Я пытаюсь получить доступ к объекту JSON из одного домена через страницу в другом. Я прочитал все, что мог найти по этому вопросу, и до сих пор не могу понять это.
Домен, обслуживающий JSON, имеет следующие настройки:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, OPTIONS"
Header set Access-Control-Allow-Headers "origin, authorization, accept"
Из другого домена я звоню по следующему адресу:
$.ajax({
type:'get',
beforeSend: function(xhr) {
var auth = // authentication;
xhr.setRequestHeader("Authorization", "Basic " + auth);
}
url:myUrl,
dataType:'json',
error: function(xhr, textStatus, errorThrown) { console.log(textStatus, errorThrown); }
})
Я знаю, что 'auth' правильно инициализирован (зарегистрирован и проверен). Однако это не работает. В консоли Firefox я получаю URL запроса: ...
Request Method:
OPTIONS
Status Code:
HTTP/1.1 401 Authorization Required
Если я избавлюсь от beforeSend:...
часть, я вижу следующее
Request Method:
GET
Status Code:
HTTP/1.1 401 Authorization Required
Однако домен, обслуживающий JSON, также может обслуживать JSONP. Я не хочу использовать это, главным образом потому, что приложение будет постоянно работать в выделенном браузере, и я беспокоюсь об этой проблеме. Что еще более важно, я действительно хотел бы знать, что на самом деле не так с тем, что я делаю. Я знаю, что для практических целей существуют различные способы преодоления утечки памяти JSONP (например, не использование jQuery).
Во всяком случае, когда я использовал JSONP, мой код выглядел так:
$.ajax({
url:newUrl,
dataType:'jsonp',
jsonp:'jsonp'
}).done(function(d){console.log(d)})
Это получает следующее
Request Method:
GET
Status Code:
HTTP/1.1 200 OK
после того, как он предложит мне с предупреждением для имени пользователя и пароля.
Есть ли принципиальное различие в том, как jQuery обрабатывает запросы JSONP, в отличие от запросов JSON? И если так, как я могу это исправить?
Благодарю.
Изменить: вот что я нашел.
В основном, потому что мне нужна аутентификация, запрос GET отправляет заголовок авторизации. Однако это не "простой" заголовок, и поэтому браузер отправляет запрос перед полетом (ОПЦИИ). Этот предварительный запрос не имеет никакой аутентификации, поэтому сервер отклонил его. "Решением" было настроить сервер так, чтобы запрос OPTIONS не требовал аутентификации, и сообщать ему состояние HTTP 200.
Ссылка: http://www.kinvey.com/blog/item/61-kinvey-adds-cross-origin-resource-sharing-cors
mail-архив [.com]/c-user@axis.apache.org/msg00790.html (запрещено размещать больше ссылок)
К сожалению, "решение" работает только на Firefox, а не на Chrome. Chrome просто показывает запрос красным, но не дает мне больше информации о том, почему он не прошел.
Редактировать 2: Исправлено в Chrome: сервер, с которого я пытался получить данные, имел сертификат безопасности, которому не доверяли. Из-за этого не удалось выполнить предпечатную проверку Chrome. Суперпользователь решения [.com]/questions/27268/how-do-i-disable-i-disable-предупреждение-chrome-дает-если-защищает-сертификат-не-доверять (запрещено публиковать больше ссылок)
3 ответа
Уэлп, теперь, когда у меня достаточно представителей, я мог бы также ответить на этот вопрос и принять его.
Когда вы пытаетесь отправить GET
JSON запрос на сервер с заголовками, браузер сначала отправляет OPTION
Просьба убедиться, что вы можете получить к нему доступ. К сожалению это OPTION
запрос не может нести с собой никакой аутентификации. Это означает, что если вы хотите отправить GET
при авторизации сервер должен разрешить OPTION без авторизации. Как только я это сделал, все стало работать.
Некоторые примеры, доступные здесь, могут дополнительно проиллюстрировать, как управление доступом может сочетаться с CORS. В частности, пример с GET. Контроль доступа требует, чтобы запрос установил withCredentials
флаг для true
на XMLHttpRequest
и для сервера, обрабатывающего OPTIONS
способ сделать две вещи:
- Задавать
Access-Control-Allow-Credentials: true
- Не использовать подстановочный знак
*
вAccess-Control-Allow-Origin
заголовок. Это должно быть установлено на источник точно в соответствии с документами MDN по управлению доступом HTTP (CORS).
По сути, объект, обрабатывающий запрос OPTIONS, должен отправить обратно соответствующие заголовки ответа, чтобы вы могли выполнить этот запрос с учетными данными.
В своем вопросе вы указали, что сервис, с которым вы взаимодействуете, возвращается Access-Control-Allow-Origin: *
, что не совместимо с междоменным запросом с полномочиями. Это необходимо для возврата происхождения специально.
Вышеупомянутая документация MDN Http Access Control (CORS) также ссылается на документацию по управлению доступом на стороне сервера, в которой описывается, как сервер может потенциально отвечать на различные междоменные запросы, включая обработку междоменного POST-запроса с междоменной областью, который требует от вас отправки правильных заголовков. в ответ на метод ОПЦИИ. Вы можете найти этот пример здесь.
Почему бы вам не попробовать ввести URL-адрес, из которого вы загружаете JSON, в свой браузер и посмотреть, что произойдет. Похоже, вам буквально нужно пройти аутентификацию на этом другом сайте, чтобы получить к нему доступ.
Если ваш сайт должен работать в других браузерах, таких как IE, вам, кстати, понадобится JSONP. Безопасность не позволит работать межсайтовому запросу. Заголовки не изменят это. Я считаю, что вам также нужно добавить политику безопасности в заголовки.