跨站点AJAX请求

我需要从一个网站向另一个域中托pipe的REST Web服务发出AJAX请求。

虽然这在Internet Explorer中工作得很好,但其他浏览器(如Mozilla和Google Chrome)却施加了更严格的安全限制,禁止跨站点AJAX请求。

问题是,我无法控制域名,也无法控制网站托pipe的网站服务器。 这意味着我的REST Web服务必须在其他地方运行,而且我无法使用任何redirect机制。

以下是进行asynchronous调用的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旁边的其他浏览器中执行此项工作?

也许JSONP可以帮助。

NB你必须改变你的消息使用JSON而不是XML

编辑

主要的网站,如Flickr和Twitter支持jsonpcallback等

标记为答案的post是错误的:iframe文档不能访问父项。 相同的原产地政策是双向的。

事实是,不可能以任何方式使用xmlhttprequest来使用基于rest的web服务。 从不同的域(没有任何框架)加载数据的唯一方法是使用JSONP。 任何其他解决scheme都需要位于您自己的域上的服务器端代理,或位于远程域上的客户端代理以及各种跨站点通信(如easyXDM )在文档之间进行通信。

这在IE浏览器工作的事实是IE的安全问题,而不是一个function。

不幸的是,跨站脚本是被禁止的,接受的解决方法是通过自己的域代理请求:你真的没有能力添加或修改服务器端代码吗?

此外,第二个解决方法 – 涉及通过脚本标记获取数据 – 只会支持GET请求,您可能能够使用SOAP服务攻击GET请求,但与您请求描述的RESTful服务的POST请求不同。

我真的不确定是否存在AJAX解决scheme,您可能会回到<form>解决scheme。

不太清楚的解决方法(但工作)是使用iframe作为容器的请求到另一个网站。 问题是,父母不能访问iframe的内容,只能导航iframe的“src”attribut。 但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 } 

使您的服务域接受跨源资源共享(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)来解决此问题。 从这里开始,你的服务器端代码应该实现一个请求/响应stream模型。

只需在您的原始域上使用服务器端代理。 这是一个例子: http : //jquery-howto.blogspot.com/2009/04/cross-domain-ajax-querying-with-jquery.html

这也可以使用一个web服务器安装程序localy来完成,该程序用正确的参数调用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的结果。

另一个select是在您自己的域上设置一个CNAMElogging来“屏蔽”远程域主机名。