跨域请求的几种方式

来源:互联网 发布:java 方法是什么 编辑:程序博客网 时间:2024/05/18 00:01

跨域的几种方式

说到跨域,我们需要了解为什么要跨域?

是因为同源策略的存在?

何谓同源策略呢?

同源策略

同源策略是浏览器上为安全性考虑实施的非常重要的安全策略。

何谓同源: URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。同源策略:浏览器的同源策略,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属性。从一个域上加载的脚本不允许访问另外一个域的文档属性。

这就是同源策略。

举个例子:

http://www.a.com:80 http://www.a.com:81 由于端口不同而不同源

http://www.a.com http://www.b.com 域名不同不同源

https://www.a.com http://www.a.com 协议不同不同源

ajax跨域

Ajax (XMLHttpRequest)请求受到同源策略的限制。Ajax通过XMLHttpRequest能够与远程的服务器进行信息交互,另外XMLHttpRequest是一个纯粹的Javascript对象,这样的交互过程,是在后台进行的,用户不易察觉。因此,XMLHTTP实际上已经突破了原有的Javascript的安全限制。如何保护自己网站的安全;可以是给XMLHTTP加上严格的同源限制 这样就能而XMLHTTP则根本上限制了跨域请求的提交  也就ajax也就失去作用了

Jsonp

 从 1.2 版本开始,jQuery 拥有对 JSONP 回调的本地支持。如果指定了 JSONP 回调,就可以加载位于另一个域的 JSON 数据 它只支持GET请求而不支持POST等其它类型的HTTP请求

proxy 跨域

代理服务器(Proxy Server)是一种重要的服务器安全功能,它的工作主要在开放系统互联(OSI)模型的会话层,从而起到防火墙的作用。代理服务器大多被用来连接INTERNET(国际互联网)和Local Area Network(局域网)

使用代理方式跨域更加直接,因为SOP的限制是浏览器实现的。如果请求不是从浏览器发起的,就不存在跨域问题了。使用本方法跨域步骤如下:1. 把访问其它域的请求替换为本域的请求2. 本域的请求是服务器端的动态脚本负责转发实际的请求

例子:

 各种服务器的Reverse Proxy功能都可以非常方便的实现请求的转发,如Apache httpd + mod_proxy。Eg.为了通过Ajax从http://localhost:8080访问http://localhost:8081/api,可以将请求发往http://localhost:8080/api。然后利用Apache Web服务器的ReverseProxy功能做如下配置:ProxyPass /apihttp://localhost:8081/api

cookie的跨域

Cookie中的同源只关注域名,忽略协议和端口。所以https://localhost:8080/和http://localhost:8081/的Cookie是共享的。

Flash/SilverLight跨域

浏览器的各种插件也存在跨域需求。通常是通过在服务器配置crossdomain.xml[4],设置本服务允许哪些域名的跨域访问。
客户端会首先请求此文件,如果发现自己的域名在访问列表里,就发起真正的请求,否则不发送请求
通常crossdomain.xml放置在网站根目录。

Iframe

iframe跨域的方式,功能强于JSONP,它不仅能用来跨域完成HTTP请求,还能在前端跨域实现JavaScript调用。因此,完全不同域的跨域问题,通常采用iframe的方式来解决。

基于iframe实现的跨域要求两个域具有aa.xx.com,bb.xx.com这种特点,也就是两个页面必须属于一个基础域(例如都是 xxx.com,或是xxx.com.cn),使用同一协议(例如都是http)和同一端口(例如都是80),这样在两个页面中同时添加document.domain,就可以实现父页面调用子页面的函数

根据前面的叙述,有了跨域文件之后,我们就可以实现通过iframe方式在不同域之间进行JavaScript调用。这个调用过程可以完全跟HTTP请求无关,例如有些站点可以支持动态地调整在页面中嵌入的第三方iframe的高度,这其实是通过在第三方iframe里面检测自己页面的高度变化,然后通过跨域方式的函数调用将这个变化告知父窗口来完成的。

既然利用iframe可以实现跨域JavaScript调用,那么跨域提交POST请求等其它类型的HTTP请求就不是难事。例如我们可以跨域调用目标域的JavaScript代码在目标域下提交Ajax请求(GET/POST/etc.),然后将返回的结果再跨域传原来的域。

使用iframe跨域,优点是功能强大,支持各种浏览器,几乎可以完成任何跨域想做的事情;缺点是实现复杂,要处理很多浏览器兼容问题,并且传输的数据不宜过大,过大了可能会超过浏览器对URL长度的限制,要考虑对数据进行分段传输等。

Cors 跨域资源共享

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simplerequest)。

只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:

§ HEAD

§ GET

§ POST

(2)HTTP的头信息不超出以下几种字段:

§ Accept

§ Accept-Language

§ Content-Language

§ Last-Event-ID

§ Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

凡是不同时满足上面两个条件,就属于非简单请求。

对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。

下面是一个例子,浏览器发现这次跨源AJAX请求是简单请求,就自动在头信息之中,添加一个Origin字段。

GET /cors HTTP/1.1Origin:http://api.bob.comHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0…

上面的头信息中,Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。

如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获

如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。

Access-Control-Allow-Origin:http://api.bob.comAccess-Control-Allow-Credentials: trueAccess-Control-Expose-Headers: FooBarContent-Type: text/html; charset=utf-8

上面的头信息之中,有三个与CORS请求相关的字段,都以Access-Control-开头。

(1)Access-Control-Allow-Origin

该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。

(2)Access-Control-Allow-Credentials

该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

(3)Access-Control-Expose-Headers

该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader(‘FooBar’)可以返回FooBar字段的值。

这就是简单请求的简单原理,希望对你们有帮助。

0 0