@panhonhang
2018-08-06T17:17:34.000000Z
字数 1423
阅读 546
JavaScript
什么是跨域资源请求?
当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。同源策略限制了一个中加载文本或者脚本与来自其他源中资源的交互方式,所谓的同源就是指协议、域名、端口相同。当浏览器执行一个脚本时会检查是否同源,只有同源的脚本才会执行,如果不同源即为跨域。
关于同源策略请参考:浏览器同源政策及其规避方法
详情参考: HTTP访问控制(CORS)
跨域的几种方式
1、JSONP
JSONP(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。JSONP之所以能够用来解决跨域方案,主要是因为 脚本拥有跨域能力,而JSONP正是利用这一点来实现。JSONP利用了 script 标签不受同源策略的限制,在页面中动态插入了 script标签,script 标签的 src 属性就是后端 api 接口的地址,并且以 get 的方式将前端回调处理函数名称告诉后端,后端在响应请求时会将回调返还,并且将数据以参数的形式传递回去。
2. CORS
跨域资源共享( CORS )机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。浏览器支持在 API 容器中(例如 XMLHttpRequest 或 Fetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险。
简单请求:
简单请求不会触发 CORS 预检请求。
若请求满足所有下述条件,则该请求可视为“简单请求”:
请求的方法使用下列方法之一:
1.GET
2.HEAD
3.POST
头信息不超过以下几种字段:
1.Accept
2.Accept-Language
3.Content-Language
4.Content-Type
仅限于下列三者之一:
text/plain
multipart/form-data
application/x-www-form-urlencoded
5.DPR
6.Downlink
7.Save-Data
8.Viewport-Width
9.Width
非简单请求:
没有同时满足以上两种情况就是非简单请求。
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
3、服务器跨域
在前后端分离的项目中可以借助服务器实现跨域,具体做法是:前端向本地服务器发送请求,本地服务器代替前端再向真实服务器接口发送请求进行服务器间通信,本地服务器其实充当个「中转站」的角色,再将响应的数据返回给前端。
4、postmessage跨域
在 HTML5 中新增了 postMessage 方法,postMessage 可以实现跨文档消息传输 Cross Document Messaging。该方法可以通过绑定 window 的 message 事件来监听发送跨文档消息传输内容。使用 postMessage 实现跨域的话原理就类似于 jsonp,动态插入 iframe标签,再从 iframe 里面拿回数据。