Django跨域资源共享问题(推荐)
作者:黑里俏
最近做了一个前后端分离的web项目,其中我司职后端,使用django框架。在前后端集成测试的时候,就遇到了一些web安全相关的问题,cors跨域资源共享就是其中之一。
cors问题介绍
跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。 CORS机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。现代浏览器支持在API容器中使用CORS,以降低跨域 HTTP 请求所带来的风险。
一个域是由协议、主机和端口号组成的,简单地说,当两个url的协议、主机和端口中存在一个不同时,它们属于不同域,那么它们之间的互相访问就会产生跨域访问问题。
我的项目中,前端的地址是 http://localhost:8001 ,后端的地址是 http://localhost:8000 ,两个地址的协议和主机都相同,但是端口号不同,因此,前端调用后端接口时,就会产生跨域访问的问题。
简单请求
简单请求不会触发跨域访问中的预检请求,满足下列条件的为简单请求:
使用下列方法之一
GET
HEAD
POST
headers字段集合主要包含以下类型:
- 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 方法。预检请求的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。 当请求满足下述任一条件时,即应首先发送预检请求:
使用了以下的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 , GET 和 OPTIONS 等等方法发起请求。
- 首部字段 Access-Control-Allow-Origin :表示服务器允许的请求源。
- 首部字段 Access-Control-Max-Age :表明该响应的有效时间为86400秒,也就是24 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。
3.然后,客户端会发出实际请求,从结果上来看,预检请求的 response 请求体中没有任何信息,而实际请求则携带了服务器返回的信息。不难看出,预检请求确实就是与服务器提前沟通,获取与服务器相关信息的。
简单的总结
非简单请求需要发送预检请求进行判断,然后服务端与客户端需要在头部字段上达成一致,这样才能正常访问。不过,在django的开发中,直接使用django-cors-headers库以后,只需要简单的配置就能够很好的解决问题。
到此这篇关于Django跨域资源共享问题小结的文章就介绍到这了,更多相关django跨域资源共享内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!