js的两种跨域请求——jsonp和cors

什么是跨域?

广义的跨域:跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。

  1. 资源跳转: A链接、重定向、表单提交
  2. 资源嵌入: 、

狭义的跨域:常说的一种跨域,由浏览器同源策略限制的一类请求场景。

什么是同源策略?
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

同源策略限制以下几种行为:

  1. Cookie、LocalStorage 和 IndexDB 无法读取
  2. DOM 和 Js对象无法获得
  3. AJAX 请求不能发送

常见跨域场景:

URL                                                           说明                                  是否允许通信
http://www.domain.com/a.js
http://www.domain.com/b.js         同一域名,不同文件或路径                  允许
http://www.domain.com/lab/c.js

http://www.domain.com:8000/a.js
http://www.domain.com/b.js         同一域名,不同端口                            不允许
 
http://www.domain.com/a.js
https://www.domain.com/b.js        同一域名,不同协议                           不允许
 
http://www.domain.com/a.js
http://192.168.4.12/b.js           域名和域名对应相同ip                               不允许
 
http://www.domain.com/a.js
http://x.domain.com/b.js           主域相同,子域不同                                  不允许
http://domain.com/c.js
 
http://www.domain1.com/a.js
http://www.domain2.com/b.js        不同域名                                             不允许

跨域解决方案 -----详情:https://segmentfault.com/a/1190000011145364
1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域

一、CORS(Cross-origin resource sharing 跨域资源共享)

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制

CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。cors依附于AJAX,通过添加HTTP Hearder部分字段请求与获取有权限访问的资源。

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

(Origin:http://www.ajdf.com:80 包括请求页面的源信息:协议 域名 端口号)有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。服务器根据这个头部信息来决定是否给予响应。

如果服务器认为这个请求可以接受,就设置Access-Control-Allow-Origin **(与请求的)相同的 源信息或者 ***

如果没有这个头部,或者有这个头部但源信息不匹配,浏览器就驳回(撤销?)请求。


服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。

使用场景:对服务器端的资源要进行一些操作的。

js的两种跨域请求——jsonp和cors_第1张图片

二、JSONP(json with padding 填充式json)

利用了使用src引用静态资源时不受跨域限制的机制。其实就是被包含在函数调用中的JSON。

JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。

jsonp主要在客户端搞一个回调做一些数据接收与操作的处理,并把这个回调函数名告知服务端,而服务端需要做的是按照javascript的语法把数据放到约定好的回调函数之中即可。

原生:
 
 // 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
 
// vue:
this.$http.jsonp('http://www.domain2.com:8080/login', {
    params: {},
    jsonp: 'handleCallback'
}).then((res) => {
    console.log(res); 
})

js的两种跨域请求——jsonp和cors_第2张图片

使用场景:兼容低版本浏览器。

CORS和JSONP的对比:-----CORS更为先进、方便和可靠。

  1. JSONP的主要优势在于对浏览器的支持较好;虽然目前主流浏览器支持CORS,但IE10以下不支持CORS。jsonp不需要依赖ajax请求受同源策略限制。而是请求完以回调函数的方式回传结果。
  2. jsonp只能实现get请求。只支持跨域http请求的情况,不能解决跨域之间页面的js调用问题。CORS支持所有类型的HTTP请求,功能完善。(这点JSONP被完虐,但大部分情况下GET已经能满足需求了)
  3. JSONP的错误处理机制并不完善,我们没办法进行错误处理;而CORS可以通过onerror事件监听错误,可以使用普通的XMLHttpRequest发起请求和获得数据,并且浏览器控制台会看到报错信息,利于排查。
  4. JSONP只会发一次请求;而对于复杂请求,CORS会发两次请求。

参考:https://www.cnblogs.com/chengdabelief/p/6685446.html
参考:https://www.zhihu.com/question/41992168/answer/217903179
参考:https://www.cnblogs.com/Koaler/p/11892205.html

你可能感兴趣的:(前端跨域)