Межсайтовые запросы AJAX

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

@PhiLho В этом случае моя цель - вызвать службу REST, размещенную в другом домене, не включая динамический контент.

Enrico Campidoglio 02.12.2008 22:56
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
23
1
30 286
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Ответ принят как подходящий

может быть, JSONP может помочь.

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

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

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

это может сработать, но JSONP - это признание того, что что-то не так :)

annakata 02.12.2008 13:24

насколько популярен этот подход? Это похоже на эксперимент.

Enrico Campidoglio 02.12.2008 13:37

@annakata, очевидно, но он заметил, что у него нет доступа к веб-серверу и т. д., поэтому использование прокси-сервера не подходит. Я здесь не для того, чтобы комментировать его ситуацию, просто предлагаю возможное решение его вопроса / проблемы.

redsquare 02.12.2008 13:50

@redsquare: согласен, он в углу @enrico: довольно экспериментально, но используется

annakata 02.12.2008 14:13

Несмотря на то, что отправка запроса AJAX из iframe, размещенного в том же домене, что и служба REST, является жизнеспособным решением (пока нет необходимости в связи между iframe и страницей), я не очень люблю iframe в целом из-за проблем с совместимостью. Так что JSONNP, вероятно, лучшее решение, доступное на данный момент.

Enrico Campidoglio 08.07.2009 12:29

но, насколько я понимаю, jsonp требует, чтобы сервер встраивал вызов функции "обратного вызова", переданной в запросе jsonp, поэтому в данной ситуации это не сработает, поскольку он не контролирует сервер ... прочтите следующее для хорошего обзора jsonp: insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html

Brad Parks 08.01.2010 20:24

Нет причин, по которым вы не могли бы использовать тот же подход для "XMLP".

Michael Mior 28.07.2011 17:38

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

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

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

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

Я согласен с тем, что разрешение XSS является недостатком безопасности в IE. К сожалению, у меня нет никакого контроля над веб-сервером, поскольку это блог, размещенный на стороннем провайдере. Я также думал об использовании HTML-форм, но это вызовет публикацию на всю страницу вместо красивого асинхронного вызова.

Enrico Campidoglio 02.12.2008 13:36

Не очень понятный обходной путь (но работает) использует 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 воспроизводится звук щелчка :(

Thinker 06.07.2009 01:42

В javascript нельзя получить доступ к родительским данным javascript или кросс-домену функций. Ответ неверен.

naugtur 23.06.2010 21:17

@nagtur: Некоторое время назад я успешно использовал этот сценарий: |.

TcKs 24.06.2010 12:57

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

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

-1, потому что это не неточно. Можно получить доступ к родительской странице из IFRAME с помощью JavaScript, используя «родительский» объект DOM. Например, это изменит элемент на странице из IFRAME: parent.document.getElementById ("someDiv"). InnerHTML = "некоторый контент";

Enrico Campidoglio 07.07.2009 16:14

Вопрос касается документа из другого домена - и поэтому будет действовать одна и та же политика происхождения. IFrame из domainA НЕ может получить доступ к contentDocument своего родителя, если родитель из domainB. Как автор межсайтовой библиотеки easyXSS, я кое-что знаю об этом.

Sean Kinsey 08.07.2009 01:58

Тогда я неправильно понял ваш ответ. Вы правы, iframe не может получить доступ к содержимому родительской страницы, и наоборот, когда они размещены в разных доменах. Однако в моем случае использование iframe работает хорошо, потому что ему не нужно каким-либо образом получать доступ к родительской странице, но он просто отправляет запрос AJAX в службу, которая размещена в том же домене.

Enrico Campidoglio 08.07.2009 12:11

Вам нужно отредактировать свой ответ, так как SO не позволит мне изменить слишком старый голос

Enrico Campidoglio 25.07.2009 16:18

easyXSS был переименован в easyXDM, и он также был немного улучшен

Sean Kinsey 13.01.2010 14:13

Просто используйте прокси на стороне сервера в своем исходном домене. Вот пример: 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 в вашем собственном домене, чтобы «замаскировать» имя хоста удаленного домена.

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