浅谈CORS

CORS全称“跨站资源共享”(Cross-Origin Resource Sharing),它允许浏览器克服浏览器同源策略向跨域服务器发出请求。

同源策略

概念

说到CORS,那么就不得不提浏览器同源策略,所谓“同源”,是指服务器URL的三个相同:

1.协议相同

2.域名相同

3.端口相同

举个栗子:比如一个URL是http://www.example.com:80/a.html,那么:

http://www.example.com:80/b.html	// 同源
https://www.example.com:80/a.html // 非同源(协议不同)
http://www.example1.com:80/a.html // 非同源(域名不同)
http://www.example.com:81/a.html // 非同源(端口不同)

限制

如果非同源,那么三种行为将受到限制:

1.非同源页面无法跨域读取浏览器本地数据存储(Cookie、LocalStorage和IndexDB)

2.非同源页面无法跨域获取DOM

3.非同源页面无法跨域发送AJAX请求

目的

那么,为什么浏览器要使用同源策略?

同源策略的目的,是为了保证用户的信息安全,防止被不法分子窃取数据。而众所周知,Cookie包含大量的登录信息,如果一个网页可以跨域访问另一个网站的Cookie,那么不法分子可以通过使用跨域访问获取Cookie然后冒充用户,为所欲为。

由此可见,同源策略是极其有必要的。

突破同源策略

但是,很多时候,我们需要跨域发送AJAX请求,此时我们就需要突破同源策略不允许发送跨域AJAX的规定。随着技术的发展,有很多技术可以实现跨域发送AJAX请求,常见的有以下三种:

1.JSONP

2.Websocket

3.CORS

JSONP

JSONP是CORS技术出来之前最常用的跨域解决方案,最大的特定是兼容性好,简单,不需要进行大的服务器改动。它的基本思路是通过动态添加一个script标签,向服务器请求脚本,脚本中一般调用一个客户端定义的函数,将数据作为参数,调用客户端的函数,而客户端通过操作该函数,可以使用被当做参数传过来的数据。

因为服务器不限制script的跨域,所以不受跨域影响。

Websocket

众所周知,Websocket是一个持久化协议,常用于解决服务器推送问题。但是,实际上Websocket其实支持跨域通信。通过设置Websocket的origin的字段,可以规定允许跨域的站点。

上面两种方法虽然可以解决跨域,但是,都有着各种问题。

庆幸的是,本文的主角:CORS的出现,彻底解决了跨域问题。

CORS

浏览器将跨域AJAX请求分为两类:简单请求和非简单请求,对应有两种不同的处理方式。

简单请求

何为简单请求?

简单请求就是满足以下两个条件的请求:

1.请求方法为HEAD、GET和POST

2.HTTP请求头只包含:AcceptAccept-LanguageContent-LanguageLast-Event-ID以及值为application/x-www-form-urlencodedmultipart/form-datatext/plain三者之一的Content-Type

对于简单请求,浏览器可以直接发送请求到服务器,但是会在请求头中添加一个origin字段,该字段用来说明请求的来源。服务器会识别该字段,判断是否允许跨域。

如果允许跨域,服务器会返回结果并在响应头上添加三个字段:

1.Access-Control-Allow-Origin

该字段的值为Origin字段的值,或者是*,表示服务器接受任何源的跨域请求。

2.Access-Control-Allow-Credentials

可选字段,它表示是否允许发送Cookie,值为true时,表示发送请求的时候允许发送Cookie,如果不包含该字段,则表示不允许发送Cookie。

值得一提的是,如果服务器允许发送Cookie,那么不允许将Access-Control-Allow-Origin的值设为*

3.Access-Control-Expose-Headers

可选字段,在没有该字段的情况下,针对跨域请求,XHR对象的getResponseHeader()方法只能拿到Cache-ControlContent-LanguageContent-TypeExpireLast-ModifiedPragma这六个字段,该字段可以设置额外可以拿到的字段。

非简单请求

不满足简单请求的跨域请求都是非简单请求,比如PUT或DELETE方法。

不同于简单请求的直接向服务器请求,非简单请求会在发送之前,先进行一次“预检”(preflight),即,向服务器发出一个OPTIONS请求,查询服务器是否允许它进行跨域请求。

如果服务器不通过“预检”,会返回一个error,客户端可以通过onerror事件进行捕获。

当服务器通过“预检”后,服务器会进行响应,响应头中含有CORS的相关字段,分别是:

1.Access-Control-Allow-Origin

该字段和简单请求中的同名字段一样。

2.Access-Control-Allow-Methods

该字段表示服务器支持跨域的所有方法,是一个逗号分隔的字符串,如:POST,DELETE。

3.Access-Control-Allow-Headers

该字段表示服务器支持的所有头信息,也是一个逗号分隔的字符串。

4.Access-Control-Allow-Credentials

可选字段,与简单请求中的同名字段一样。

5.Access-Control-Max-Age

可选字段,在一段时间内,浏览器对同一个域名进行非简单跨域请求,只对第一次进行“预检”,而这一次“预检”的结果将被缓存,接下来的请求都通过该结果进行判断。该字段就是用来设置“预检”结果缓存的时间长短,可以将其值设为-1来禁用“预检”缓存。

接收到服务器通过“预检”的响应后,客户端会正式发送真正的请求,接下来的处理方式和简单请求一致。

总结

在当前开发中,当不需要兼容老式浏览器中,我们一般采用CORS的方式进行跨域请求,因为相比Websocket,CORS支持非长连接场景;相比JSONP,CORS支持所有HTTP请求,用法更加平滑。

当然,值得一提的是,当你需要兼容老式浏览器时,JSONP是你唯一的选择~

浅谈CORS的更多相关文章

  1. 浅谈Hybrid技术的设计与实现

    前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hybrid技术的设计与实现第三弹——落地篇 随着移动浪潮的兴起,各种APP层出不穷,极速的业务扩展提升了团队对开发 ...

  2. 浅谈JS之AJAX

    0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HT ...

  3. (转)浅谈Hybrid技术的设计与实现

    转载地址:https://www.cnblogs.com/yexiaochai/p/4921635.html 前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hyb ...

  4. 浅谈Hybrid技术的设计与实现【转】

    https://www.cnblogs.com/yexiaochai/p/4921635.html 前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hybrid技术 ...

  5. 浅谈异步上传插件 jquery-file-upload插件

    当我们需要异步上传文件的时候,我们倾向于在网上查找相关的JQuery插件,jquery-file-upload就是我们经常看到的,但是他的主页是英文的,对于我们这些英语比较差的同学来说,简直就是... ...

  6. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  7. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  8. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  9. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

随机推荐

  1. 8.31前端 jQuery

    2018-8-31 19:52:09 周末吧这几天课看完 结束前端!然后进行Django!!! 越努力,越幸运! day56 2018-03-16 1. 内容回顾 1. 样式操作 1. 操作class ...

  2. OpenCV Save CvRect to File 保存CvRect变量到文件

    在OpenCv中,我们有时候需要查看CvRect变量的值,我们可以通过将其保存到文件来查看,保存的代码如下: void writeCvRectToFile(CvRect &rect, cons ...

  3. 为什么 Redis 重启后没有正确恢复之前的内存数据

    安装 Redis 后,默认配置下启动会得到如下日志: [] Sep ::! Background save may fail under low memory condition. To fix th ...

  4. Python 之反射和普通方式对比(模拟Web框架)

    先模拟一个web页面的选择不同输出不同 vim day8-7.py #!/usr/bin/python # -*- coding:utf-8 -*- import home import accoun ...

  5. 牛客网多校赛第九场A-circulant matrix【数论】

    链接:https://www.nowcoder.com/acm/contest/147/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...

  6. 2018java面试知识汇总

    1. 多线程 1.1 多线程7种同步方法? 答:同步方法 同步代码块 使用重入锁实现线程同步(ReentrantLock) 使用特殊域变量(volatile)实现同步(每次重新计算,安全但并非一致) ...

  7. CodeForces - 798D Mike and distribution 想法题,数学证明

    题意:给你两个数列a,b,你要输出k个下标,使得这些下标对应的a的和大于整个a数列的和的1/2.同时这些下标对应的b //题解:首先将条件换一种说法,就是要取floor(n/2)+1个数使得这些数大于 ...

  8. .Net Identity OAuth 2.0 SecurityStamp 使用

    起源: 近期帮别人做项目,涉及到OAuth认证,服务端主动使token失效,要使对应用户不能再继续访问,只能重新登陆,或者重新授权. 场景: 这种场景OAuth2.0是支持的,比如用户修改了密码,那所 ...

  9. centos7 卸载和安装最新版本docker-ce,配置阿里云加速

    一.yum卸载.安装 1.卸载老版本的 docker 及其相关依赖 sudo yum remove docker docker-common container-selinux docker-seli ...

  10. Python开发【笔记】:什么是RESTful框架

    RESTful框架 前言:  一句话总结:用URL定位资源,用HTTP描述操作 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式 ...