Django跨域资源共享问题小结

摘要

最近作了一个先后端分离的web项目,其中我司职后端,使用django框架。在先后端集成测试的时候,就遇到了一些web安全相关的问题,cors跨域资源共享就是其中之一。前端

cors问题介绍

跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不一样源服务器上的指定的资源。当一个资源从与该资源自己所在的服务器不一样的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。 CORS机制容许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。现代浏览器支持在API容器中使用CORS,以下降跨域 HTTP 请求所带来的风险。web

一个域是由协议、主机和端口号组成的,简单地说,当两个url的协议、主机和端口中存在一个不一样时,它们属于不一样域,那么它们之间的互相访问就会产生跨域访问问题。django

url

个人项目中,前端的地址是http://localhost:8001,后端的地址是http://localhost:8000,两个地址的协议和主机都相同,可是端口号不一样,所以,前端调用后端接口时,就会产生跨域访问的问题。后端

简单请求

简单请求不会触发跨域访问中的预检请求,知足下列条件的为简单请求:跨域

  • 使用下列方法之一
    • GET
    • HEAD
    • POST
  • headers字段集合主要包含如下类型:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-type:text/plainmultipart/form-dataapplication/x-www-form-urlencoded
    • DRP
    • DownLink
    • Save-Data
    • Viewport-Width
    • Width

非简单请求

非简单请求即不知足简单请求条件的请求。非简单请求在发出请求前须要先发送一个预检请求,请求方法为OPTIONS方法。预检请求的使用,能够避免跨域请求对服务器的用户数据产生未预期的影响。 当请求知足下述任一条件时,即应首先发送预检请求:浏览器

  • 使用了如下的HTTP方法:
    • PUT
    • DELETE
    • CONNECT
    • OPTIONS
    • TRACE
    • PATCH
  • 首部字段里面包含了非简单请求的头部字段的字段

django中遇到的问题

在后台开发中,就遇到了这样的状况缓存

错误提示中显示,请求被CORS协议阻拦。安全

这里的 Origin字段说明了请求源地址,采用了 OPTIONS方法,而后发出请求的地址 Host就是本机地址。下面是服务器的响应,可是没有发出实际请求
而后,为了解决这一问题,我搜索事后,安装了django-cors-headers库,而且进行了配置,这里配置时我把django-cors-headers中间件放在了中间件第一位。再次访问一样的地址,结果以下:

预检请求

  1. 首先,浏览器检测访问的请求头中的字段,存在对CORS安全的首部字段集合以外的字段,因此,向服务器发送一个预检请求。上图可见,方法为OPTIONS,该方法不会对服务器资源产生影响。其中的请求头中的Access-Control-Request-Method字段代表实际请求会采用GET方法,Origin表示请求源,会在服务器中接受验证。
  2. 验证经过后,会在response请求头添加不一样的字段进行返回, 字段的意思以下:
    • 首部字段Access-Control-Allow-Headers:表示服务器容许的头部字段。
    • 首部字段Access-Control-Allow-Methods:代表服务器容许客户端使用 POST, GETOPTIONS 等等方法发起请求。
    • 首部字段Access-Control-Allow-Origin:表示服务器容许的请求源。
    • 首部字段Access-Control-Max-Age:代表该响应的有效时间为86400秒,也就是24 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。
  3. 而后,客户端会发出实际请求,从结果上来看,预检请求的response请求体中没有任何信息,而实际请求则携带了服务器返回的信息。不难看出,预检请求确实就是与服务器提早沟通,获取与服务器相关信息的。

简单的总结

非简单请求须要发送预检请求进行判断,而后服务端与客户端须要在头部字段上达成一致,这样才能正常访问。不过,在django的开发中,直接使用django-cors-headers库之后,只须要简单的配置就可以很好的解决问题。服务器

存在的问题

我在测试时尝试使用本身写的中间件来补充头部信息,可是在浏览器清除缓存后,就会致使登陆异常,而且浏览器没有显示预检请求。等问题解决后,会把问题和解决方案再更新上来。app

参考的资料

MDN:HTTP访问控制(CORS)
跨域——CORS详解

若是有什么不对之处欢迎指正!

相关文章
相关标签/搜索