Запрос ajax на перекрестный поддомен отклонен, даже если document.domain установлен правильно

#javascript #jquery #json #cross-domain #jsonp

#javascript #jquery #json #междоменный #jsonp

Вопрос:

В моем приложении у меня есть веб-сайт в одном поддомене (dev.u413.com ) и я использую jQuery для отправки ajax-запроса к JSON api в другом поддомене (api.u413.com ). Когда я проверяю запросы в Chrome dev tools и Firefox Firebug, кажется, что мои запросы предотвращаются Access-Control-Allowed-Origin . Я установил document.domain суффикс текущего домена: document.domain = 'u413.com'; .

Вот мой запрос:

     $.ajax({
        dataType: 'json',
        data: { parseAsHtml: true, cli: 'help' },
        url: 'http://api.u413.com/',
        success: function (response) {
            alert(response.Command);
        }
    });
  

Если я изменю запрос ajax, чтобы он находился в том же домене, запрос будет выполнен успешно.

     $.ajax({
        dataType: 'json',
        crossDomain: false,
        data: { parseAsHtml: true, cli: 'help' },
        url: 'http://dev.u413.com/',
        success: function (response) {
            alert(response.Command);
        }
    });
  

Почему это происходит? Браузер не должен жаловаться на междоменные проблемы, поскольку я установил document.domain общий суффикс для обоих поддоменов в соответствии с рекомендациями по политике одного и того же источника.

В настоящее время у меня есть приложение, работающее с jsonp, но я чувствую, что правильные запросы ajax должны работать в соответствии с той же политикой происхождения, которую я ссылал выше. Я бы предпочел не использовать jsonp, если мне это не нужно. Разве невозможно отправлять регулярные ajax-запросы через поддомены?

Комментарии:

1. Я не хочу jsonp, это моя точка зрения. Я хочу выполнить правильный AJAX-запрос по поддоменам, который должен быть разрешен в соответствии с той же политикой происхождения .

2. @ALex Я прочитал этот документ, теперь я думаю о другом способе 🙂

3. @DarinDimitrov как бы я установил его в домене api? Это просто api, который возвращает данные JSON. (например api.u413.com/?cli=help )

4. @AlexFord, неважно, я допустил ошибку и удалил свой комментарий. document.domain не имеет отношения к вашему сценарию, поскольку вы выполняете AJAX. Смотрите мой ответ.

Ответ №1:

document.domain не работает с AJAX. Он предназначен для междоменной связи iframe и window. В вашем случае вы нарушаете ту же политику происхождения (последняя строка таблицы), поэтому вам нужно использовать либо JSONP, либо серверный мост.

Вот очень хорошее руководство, которое иллюстрирует различные методы для достижения междоменных AJAX-запросов.

Комментарии:

1. А, ладно. Спасибо за помощь. У меня уже есть работа с JSONP, и это нормально. Я был просто разочарован тем, что не мог заставить его работать, когда думал, что это должно работать именно так. Еще раз спасибо.

2. В «хорошем руководстве» говорится, что сайт был взломан: (

3. Итак, если я использую iframe и получаю содержимое iframe с помощью javascript, он должен работать?

4. Вздох… Ваше хорошее руководство «взломано злоумышленником Ben».

5. Почему все ведут себя так, как будто JSONP что- то решает. Хорошо, продолжайте, попробуйте выполнить CORS POST с помощью JSONP и посмотрите, как далеко это вас заводит.

Ответ №2:

одна и та же политика происхождения — одна из самых неприятных тем, связанных с браузером, с которыми мне приходилось сталкиваться. Мне кажется глупым, что 2 сервера в одном домене не могут обмениваться данными. К сожалению, одна и та же политика происхождения рассматривает даже 2 запроса к одному и тому же серверу, но на другом порту, как нарушение одной и той же политики происхождения. Я думаю, что это улучшится в будущих браузерах:

http://www.html5rocks.com/en/tutorials/file/xhr2/

поиск: совместное использование ресурсов разных источников (CORS)

по сути, вашему серверу просто нужно установить заголовок ответа, в котором говорится: «Да, можно разрешить междоменные или междоменные вызовы на сервер xyz».

Пройдет некоторое время, прежде чем все браузеры поддержат это, я уверен (и, черт возьми, я должен поддерживать ie8, пока большинство наших пользователей все равно не отключат его), но, по крайней мере, есть свет в конце туннеля.

Ответ №3:

Вам также необходимо добавить document.domain = 'u413.com в свой другой поддомен.

Комментарии:

1. Куда мне это добавить? Это api, который возвращает только JSON.

2. @Alex, тогда JSONP — это правильный путь. document.domain позволяет сотрудничать только двум документам .

3. Может быть, и нет, но до CORS особого выбора не было.

Ответ №4:

Разве невозможно отправлять регулярные ajax-запросы через поддомены?

Технически это не AJAX, но вы можете имитировать AJAX-запрос, успешно отправив форму в междоменном режиме. Недостатком является то, что вы не можете получить доступ к ответу, и это приведет к перенаправлению страницы на ACTION URL формы.

Вместо этого:

 jQuery.post('https://www.com',
    'offerCode':523153,
    'accountNumber':'',
    '_item.x':'42',
    '_item.y':'21'
});
  

Используйте это:

 jQuery('<form action="https://www.com" method="POST">
      <input type="text" name="offerCode" value="523153">
      <input type="text" name="accountNumber" value="">
      <input type="text" name="_item.x" value="42">
      <input type="text" name="_item.y" value="21">
    </form>').trigger('submit');