内容简介:跨域总结
如果两个页面的不具有相同的 源
,即 协议
、 端口
、 子域名
有任意一个不同,如果使用 XMLHttpRequest
或者 fetch
就会产生跨域(跨域并非浏览器限制了发起跨站请求,而是跨站请求可以正常发起,但是返回结果被浏览器拦截了。最好的例子是CSRF跨站攻击原理,请求是发送到了后端服务器无论是否跨域!)
跨域的解决方法
CROS
CORS 是一个W3C标准,全称是” 跨域资源共享
“(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。
如何实现 CROS
CROS 需要 浏览器
和 服务器
同时支持,关键是 服务器
简单请求
只要同时满足以下两大条件,就属于简单请求。
- 请求方法是以下三种方法之一:
- HEAD
- GET
- POST
- HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
基本原理
基本原理是浏览器发送的header信息中增加了一个 Origin
字段
GET /cors HTTP/1.1 Origin: http://api.bob.com Host: api.alice.com Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
然后服务器根据这个值,决定是否同意这次请求,若origin指定的源不在范围之内,服务器会返回一个不带有 Access-Control-Allow-Control
字段的信息,浏览器收到就会抛出一个错误。如果Origin指定的域名在许可范围内,服务器返回的信息会多出几个头信息字段。
// 正常返回 Access-Control-Allow-Origin: http://api.bob.com // * 的表示接受任意域名的请求 Access-Control-Allow-Credentials: true // 是否发送 cookie Access-Control-Expose-Headers: FooBar // 获取其他指定 header 字段 Content-Type: text/html; charset=utf-8
非简单请求
请求方法是 PUT
或 DELETE
,或者 Content-Type
字段的类型是 application/json
。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为 "预检"请求
(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
JSONP
Jsonp(JSON with Padding) 是 json 的一种”使用模式”,可以让网页从别的域名(网站)那获取资料,即跨域读取数据。
例子
- 客户请求数据url: http://www.runoob.com/try/ajax/jsonp.php?jsonp=callbackFunction
- 客户期望返回的json数据:{“name”: “ruansongsong”}
- 真正返回客户端的数据:callback({“name”: “ruansongsong”})
解释:客户端请求的 URL中会带有一个回调函数
,服务器收到这个请求会将数据包装到回调函数中,然后返回给客户端,返回的函数就会 调用
客户端写的那个回调函数,也就实现了跨域访问
缺点: 只支持GET
,非常易用遭到跨站请求伪造(cross-site request forgery)的攻击
JSONP的原生使用需要动态创建script标签
<scripttype="text/javascript"> // 得到航班信息查询结果后的回调函数 var flightHandler = function(data){ alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。'); }; // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码) var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler"; // 创建script标签,设置其属性 var script = document.createElement('script'); script.setAttribute('src', url); // 把script标签加入head,此时调用开始 document.getElementsByTagName('head')[0].appendChild(script); </script>
图像 Ping
<img>
的 src
属性不用担心跨域,可以动态的创建图像,使用他们的 onload
和 onerror
事件处理程序来确定是否接收到了响应。 简单
、 单向
的跨域,请求的数据是通过查询字符串形式发送的,而响应内容通常是像素图或 204 响应。
实例代码
var img = new Image(); img.onload = function(){ console.log('done'); // 请求完成便会通知 } img.src = "http://www.example.com/test?name=ruansongsong";
缺点
通常用于跟踪用户点击页面或动态广告曝光次数,只能用于 GET
请求, 无法访问服务器响应的文本
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
迎接互联网的明天
邹静 / 电子工业 / 2011-6 / 55.00元
《迎接互联网的明天-玩转3D Web(附盘)》,全书共5章,第1章主要阐述了国内外空前繁荣的3D互联网技术领域,以及这些领域透射出来的潜在商机;第2章主要用当下比较流行的Flash编程语言ActionScript 3,来向大家介绍面向对象编程语言的思想概念,以及一些3D渲染技术的入门知识;第3章注重建模知识的运用,主要运用WireFusion和3ds Max来制作3D网页;第4章主要介绍3D游戏编......一起来看看 《迎接互联网的明天》 这本书的介绍吧!