Межсайтовые запросы AJAX - PullRequest
23 голосов
/ 02 декабря 2008

Мне нужно сделать запрос AJAX с веб-сайта на веб-службу REST, размещенную в другом домене.

Хотя это отлично работает в Internet Explorer, другие браузеры, такие как Mozilla и Google Chrome, накладывают гораздо более строгие ограничения безопасности, которые запрещают межсайтовые запросы AJAX.

Проблема в том, что я не могу контролировать ни домен, ни веб-сервер, на котором размещен сайт. Это означает, что мой веб-сервис REST должен работать где-то еще, и я не могу задействовать какой-либо механизм перенаправления.

Вот код JavaScript, который выполняет асинхронный вызов:

var serviceUrl = "http://myservicedomain";
var payload = "<myRequest><content>Some content</content></myRequest>";
var request = new XMLHttpRequest();
request.open("POST", serviceUrl, true); // <-- This fails in Mozilla Firefox amongst other browsers
request.setRequestHeader("Content-type", "text/xml");
request.send(payload);

Как это можно сделать в других браузерах, кроме Internet Explorer?

Ответы [ 8 ]

14 голосов
/ 02 декабря 2008

возможно JSONP может помочь.

NB. Вам придется изменить свои сообщения, чтобы использовать json вместо xml

Редактировать

Основные сайты, такие как flickr и twitter , поддерживают jsonp с обратными вызовами и т. Д.

5 голосов
/ 06 июля 2009

Сообщение, помеченное как ответ, является ошибочным: документ iframes НЕ имеет доступа к родительскому элементу. Одна и та же политика происхождения работает в обе стороны.

Дело в том, что никоим образом невозможно использовать основанный на отдыхе веб-сервис с использованием xmlhttprequest. Единственный способ загрузить данные из другого домена (без какой-либо структуры) - это использовать JSONP. Любые другие решения требуют наличия серверного прокси-сервера, расположенного в вашем собственном домене, или клиентского прокси-сервера, расположенного в удаленном домене, и некоторого рода межсайтовой связи (например, easyXDM ) для обмена данными между документами.

3 голосов
/ 02 декабря 2008

Не очень понятный обходной путь (но работает) использует iframe в качестве контейнера для запросов к другим сайтам. Проблема в том, что родитель не может получить доступ к содержимому iframe, может перемещаться только по атрибуту iframe "src". Но контент iframe может обращаться к контенту родителя.

Таким образом, если контент iframe знает, они могут вызывать некоторый контент javascript на родительской странице или напрямую обращаться к DOM родителей.

EDIT: Пример:

function ajaxWorkaroung() {
    var frm = gewtElementById("myIFrame")
    frm.src = "http://some_other_domain"
}
function ajaxCallback(parameter){
    // this function will be called from myIFrame's content
}
3 голосов
/ 02 декабря 2008

Тот факт, что это работает в IE, является проблемой безопасности IE, а не функцией.

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

Кроме того, вторичный обходной путь, включающий получение данных с помощью тегов сценария, будет поддерживать только запросы GET, которые можно будет взломать с помощью службы SOAP, но не так сильно с помощью запроса POST к службе RESTful Вы описываете.

Я действительно не уверен, что существует решение AJAX, возможно, вы вернулись к решению .

2 голосов
/ 07 июля 2012

Сделайте так, чтобы ваш сервисный домен принимал кросс-ресурсное совместное использование ресурсов (CORS).

Типичный сценарий: большинство CORS-совместимых браузеров сначала отправляют заголовок OPTIONS, в который сервер должен возвращать информацию о том, какие заголовки приняты. Если заголовки удовлетворяют требованиям службы для предоставленного запроса (разрешенными методами являются GET и POST, Allowed-Origin * и т. Д.), Браузер затем повторно отправит запрос соответствующим методом (GET, POST и т. Д.).

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

Caviots: некоторые SDK для разработки сервисов (в частности, WCF) будут пытаться обработать запрос, в этом случае вам необходимо предварительно обработать метод OPTIONS, чтобы ответить на запрос и избежать повторного вызова метода на сервере.

Короче говоря, проблема лежит на стороне сервера.

Редактировать Существует одна проблема с IE 9 и ниже с CORS в том, что она не полностью реализована. К счастью, вы можете решить эту проблему, выполнив вызовы из серверного кода в службу и вернуть его через ваш сервер (например, mypage.aspx? Service = blah & method = blahblah & p0 = firstParam = что-то). Отсюда ваш код на стороне сервера должен реализовывать модель потока запросов / ответов.

1 голос
/ 04 января 2012

Просто используйте серверный прокси в вашем домене происхождения. Вот пример: http://jquery -howto.blogspot.com / 2009/04 / cross-domain-ajax-querying-with-jquery.html

0 голосов
/ 07 декабря 2013

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

0 голосов
/ 26 августа 2012

Это также можно сделать с помощью локальной настройки веб-сервера, которая вызывает curl с правильными аргументами и возвращает вывод curl.

app.rb

require 'sinatra'
require 'curb'

set :views,lambda {"views/"+self.name.to_s.downcase.sub("controller","")}
set :haml, :layout => :'../layout', :format => :html5, :escape_html=>true
disable :raise_errors

get '/data/:brand' do
  data_link =  "https://externalsite.com/#{params[:brand]}"
  c = Curl::Easy.perform(data_link)
  c.body_str
end

Отправка ajax-запроса на localhost: 4567 / data / что-то вернет результат с externalsite.com/something.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...