最近作了一个先后端分离的web项目,其中我司职后端,使用django框架。在先后端集成测试的时候,就遇到了一些web安全相关的问题,cors跨域资源共享就是其中之一。前端
跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不一样源服务器上的指定的资源。当一个资源从与该资源自己所在的服务器不一样的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。 CORS机制容许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。现代浏览器支持在API容器中使用CORS,以下降跨域 HTTP 请求所带来的风险。web
一个域是由协议、主机和端口号组成的,简单地说,当两个url的协议、主机和端口中存在一个不一样时,它们属于不一样域,那么它们之间的互相访问就会产生跨域访问问题。django
个人项目中,前端的地址是http://localhost:8001
,后端的地址是http://localhost:8000
,两个地址的协议和主机都相同,可是端口号不一样,所以,前端调用后端接口时,就会产生跨域访问的问题。后端
简单请求不会触发跨域访问中的预检请求,知足下列条件的为简单请求:跨域
GET
HEAD
POST
Accept
Accept-Language
Content-Language
Content-type
:text/plain
、multipart/form-data
和application/x-www-form-urlencoded
DRP
DownLink
Save-Data
Viewport-Width
Width
非简单请求即不知足简单请求条件的请求。非简单请求在发出请求前须要先发送一个预检请求,请求方法为OPTIONS
方法。预检请求的使用,能够避免跨域请求对服务器的用户数据产生未预期的影响。 当请求知足下述任一条件时,即应首先发送预检请求:浏览器
PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCH
在后台开发中,就遇到了这样的状况缓存
错误提示中显示,请求被CORS
协议阻拦。安全
Origin
字段说明了请求源地址,采用了
OPTIONS
方法,而后发出请求的地址
Host
就是本机地址。下面是服务器的响应,可是没有发出实际请求
CORS
安全的首部字段集合以外的字段,因此,向服务器发送一个预检请求。上图可见,方法为OPTIONS
,该方法不会对服务器资源产生影响。其中的请求头中的Access-Control-Request-Method
字段代表实际请求会采用GET
方法,Origin
表示请求源,会在服务器中接受验证。response
请求头添加不一样的字段进行返回, 字段的意思以下:
Access-Control-Allow-Headers
:表示服务器容许的头部字段。Access-Control-Allow-Methods
:代表服务器容许客户端使用 POST
, GET
和 OPTIONS
等等方法发起请求。Access-Control-Allow-Origin
:表示服务器容许的请求源。Access-Control-Max-Age
:代表该响应的有效时间为86400秒,也就是24 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。response
请求体中没有任何信息,而实际请求则携带了服务器返回的信息。不难看出,预检请求确实就是与服务器提早沟通,获取与服务器相关信息的。非简单请求须要发送预检请求进行判断,而后服务端与客户端须要在头部字段上达成一致,这样才能正常访问。不过,在django的开发中,直接使用django-cors-headers库之后,只须要简单的配置就可以很好的解决问题。服务器
我在测试时尝试使用本身写的中间件来补充头部信息,可是在浏览器清除缓存后,就会致使登陆异常,而且浏览器没有显示预检请求。等问题解决后,会把问题和解决方案再更新上来。app
若是有什么不对之处欢迎指正!