Мне нужно сделать запрос 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?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


может быть, JSONP может помочь.
NB, вам придется изменить свои сообщения, чтобы использовать json вместо xml.
Редактировать
Основные сайты, такие как flickr и твиттер, поддерживают jsonp с обратными вызовами и т. д.
это может сработать, но JSONP - это признание того, что что-то не так :)
насколько популярен этот подход? Это похоже на эксперимент.
@annakata, очевидно, но он заметил, что у него нет доступа к веб-серверу и т. д., поэтому использование прокси-сервера не подходит. Я здесь не для того, чтобы комментировать его ситуацию, просто предлагаю возможное решение его вопроса / проблемы.
@redsquare: согласен, он в углу @enrico: довольно экспериментально, но используется
Несмотря на то, что отправка запроса AJAX из iframe, размещенного в том же домене, что и служба REST, является жизнеспособным решением (пока нет необходимости в связи между iframe и страницей), я не очень люблю iframe в целом из-за проблем с совместимостью. Так что JSONNP, вероятно, лучшее решение, доступное на данный момент.
но, насколько я понимаю, jsonp требует, чтобы сервер встраивал вызов функции "обратного вызова", переданной в запросе jsonp, поэтому в данной ситуации это не сработает, поскольку он не контролирует сервер ... прочтите следующее для хорошего обзора jsonp: insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html
Нет причин, по которым вы не могли бы использовать тот же подход для "XMLP".
Тот факт, что это работает в IE, является проблемой безопасности IE, а не функцией.
К сожалению, межсайтовый скриптинг запрещен, и принято решение проксировать запросы через ваш собственный домен: действительно ли у вас нет возможности добавлять или изменять код на стороне сервера?
Кроме того, вторичный обходной путь, связанный с получением данных с помощью тегов сценария, будет поддерживать только запросы GET, которые вы можете взломать с помощью службы SOAP, но не столько с помощью запроса POST к службе RESTful, которую вы описываете.
Я действительно не уверен, что существует решение AJAX, возможно, вы вернетесь к решению <form>.
Я согласен с тем, что разрешение XSS является недостатком безопасности в IE. К сожалению, у меня нет никакого контроля над веб-сервером, поскольку это блог, размещенный на стороннем провайдере. Я также думал об использовании HTML-форм, но это вызовет публикацию на всю страницу вместо красивого асинхронного вызова.
Не очень понятный обходной путь (но работает) использует iframe в качестве контейнера для запросов к другим сайтам. Проблема в том, что родитель не может получить доступ к содержимому iframe, может только перемещаться по атрибуту iframe "src". Но содержимое iframe может получить доступ к родительскому содержимому.
Итак, если содержимое iframe известно, они могут вызывать некоторый контент javascript на родительской странице или напрямую обращаться к родительской DOM.
Обновлено: Образец:
function ajaxWorkaroung() {
var frm = gewtElementById("myIFrame")
frm.src = "http://some_other_domain"
}
function ajaxCallback(parameter){
// this function will be called from myIFrame's content
}
IFrames медленнее, чем ajax, а также в более старом IE, я помню, что при каждом обновлении iframe.src воспроизводится звук щелчка :(
В javascript нельзя получить доступ к родительским данным javascript или кросс-домену функций. Ответ неверен.
@nagtur: Некоторое время назад я успешно использовал этот сценарий: |.
Сообщение, помеченное как ответ, ошибочно: документ iframe НЕ может получить доступ к родительскому элементу. Одна и та же политика происхождения работает в обоих направлениях.
Дело в том, что никаким образом невозможно использовать основанный на отдыхе веб-сервис с помощью xmlhttprequest. Единственный способ загрузить данные из другого домена (без какой-либо структуры) - использовать JSONP. Для любых других решений требуется прокси на стороне сервера, расположенный в вашем собственном домене, или прокси на стороне клиента, расположенный в удаленном домене, и некоторая межсайтовая связь (например, easyXDM) для связи между документами.
-1, потому что это не неточно. Можно получить доступ к родительской странице из IFRAME с помощью JavaScript, используя «родительский» объект DOM. Например, это изменит элемент на странице из IFRAME: parent.document.getElementById ("someDiv"). InnerHTML = "некоторый контент";
Вопрос касается документа из другого домена - и поэтому будет действовать одна и та же политика происхождения. IFrame из domainA НЕ может получить доступ к contentDocument своего родителя, если родитель из domainB. Как автор межсайтовой библиотеки easyXSS, я кое-что знаю об этом.
Тогда я неправильно понял ваш ответ. Вы правы, iframe не может получить доступ к содержимому родительской страницы, и наоборот, когда они размещены в разных доменах. Однако в моем случае использование iframe работает хорошо, потому что ему не нужно каким-либо образом получать доступ к родительской странице, но он просто отправляет запрос AJAX в службу, которая размещена в том же домене.
Вам нужно отредактировать свой ответ, так как SO не позволит мне изменить слишком старый голос
easyXSS был переименован в easyXDM, и он также был немного улучшен
Просто используйте прокси на стороне сервера в своем исходном домене. Вот пример: http://jquery-howto.blogspot.com/2009/04/cross-domain-ajax-querying-with-jquery.html
Сделайте так, чтобы ваш служебный домен принимал совместное использование ресурсов из разных источников (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 = something). Отсюда ваш серверный код должен реализовывать модель потока запросов / ответов.
Это также можно сделать, используя локальную настройку веб-сервера, которая вызывает 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 / something вернет результат с externalsite.com/something.
Другой вариант - настроить запись CNAME в вашем собственном домене, чтобы «замаскировать» имя хоста удаленного домена.
@PhiLho В этом случае моя цель - вызвать службу REST, размещенную в другом домене, не включая динамический контент.