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 способ сделать две вещи:

  1. Задавать Access-Control-Allow-Credentials: true
  2. Не использовать подстановочный знак * в Access-Control-Allow-Origin заголовок. Это должно быть установлено на источник точно в соответствии с документами MDN по управлению доступом HTTP (CORS).

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

В своем вопросе вы указали, что сервис, с которым вы взаимодействуете, возвращается Access-Control-Allow-Origin: *, что не совместимо с междоменным запросом с полномочиями. Это необходимо для возврата происхождения специально.

Вышеупомянутая документация MDN Http Access Control (CORS) также ссылается на документацию по управлению доступом на стороне сервера, в которой описывается, как сервер может потенциально отвечать на различные междоменные запросы, включая обработку междоменного POST-запроса с междоменной областью, который требует от вас отправки правильных заголовков. в ответ на метод ОПЦИИ. Вы можете найти этот пример здесь.

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

Если ваш сайт должен работать в других браузерах, таких как IE, вам, кстати, понадобится JSONP. Безопасность не позволит работать межсайтовому запросу. Заголовки не изменят это. Я считаю, что вам также нужно добавить политику безопасности в заголовки.

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