django结合OPTIONS⽅法处理跨域请求(单个视图⽅法中)
OPTIONS ⽅法⽐较少见,该⽅法⽤于请求服务器告知其⽀持哪些其他的功能和⽅法。通过 OPTIONS ⽅法,可以询问服务器具体⽀持哪些⽅法,或者服务器会使⽤什么样的⽅
法来处理⼀些特殊资源。可以说这是⼀个探测性的⽅法,客户端通过该⽅法可以在不访问服务器上实际资源的情况下就知道处理该资源的最优⽅式。
既然⽐较少见,什么情况下会使⽤这个⽅法呢?
假设在 edx.open 域下发起了⼀个跨域的 POST 请求,期望提交数据到 api.sit 这个域名的服务器。
在进⾏发送POST请求前,会⾃动先发起⼀个 OPTIONS 请求,其请求头包含了的⼀些关键性字段:
1 OPTIONS /upload/ HTTP/1.1
2 Access-Control-Request-Method: POST
3 Access-Control-Request-Headers: accept, content-type
4 Origin: edx.open
5 ...
这种场景下,客户端发起的这个 OPTIONS 可以说是⼀个“预请求”,⽤于探测后续真正需要发起的跨域 POST 请求对于服务器来说是否是安全可接受的,因为跨域提交数据对于
服务器来说可能存在很⼤的安全问题。
请求头 Access-Control-Request-Method ⽤于提醒服务器在接下来的请求中将会使⽤什么样的⽅法来发起请求。
那么在服务端应该如何处理这个 OPTIONS 请求呢?
响应上⾯的 OPTIONS 请求时,需要添加上⽤于访问控制的响应头。
响应头中关键性的字段:
1 Access-Control-Allow-Method: POST
2 Access-Control-Allow-Origin: edx.open
3 Access-Control-Allow-Headers: X-CSRFToken, Content-Type
Access-Control-Allow-Method 和 Access-Control-Allow-Origin 分别告知客户端,服务器允许客户端⽤于跨域的⽅法和域名。
完整处理流程如下:
⼀.在视图(我定义的是类视图)中定义OPTIONS⽅法: def options(self, request, *args, **kwargs)/获取请求头的 Access-Control-Request-Method 和 Origin 参数
1 method = ('Access-Control-Allow-Method')
2 origin = ('Origin')
⼆.在def options(self, request, *args, **kwargs) ⽅法中设置响应头信息,返回response对象
1 response = Response()
2 response['Access-Control-Allow-Method'] = method # ⽀持那些请求⽅法,可以根据实际情况配置如 "POST, GET ,OPTIONS"
3 response['Access-Control-Allow-Origin'] = origin # 实际操作中本⼈⽆法获取请求头中的Origin参数,所以这⾥我实际上是配置成了 "*",但是不建议这样操作,后续会有问题,可以根据实际情况写成固定的也可以 "完整域名"
4 response["Access-Control-Allow-Headers"] = "X-CSRFToken, Content-Type" # 如果配置接收的请求头有遗漏,当发送OPTIONS⽅法成功后,发送正式请求时将会在浏览器报错,可以根据浏览器中consolo的报错内容添加进去即可, 我这⾥需要配置
5 return response
# OPTION⽅法定义完成后,还需要在正式的视图⽅法中的响应对象中配置⼀样的响应头信息,这⾥不再重复了,⾄此,该视图⽅法就⽀持跨域请求了。
# 需要留意的是,jquery发送OPTIONS请求时,默认将不会携带cookie信息,如果此时该视图需要进⾏登录验证(跨域请求,却要进⾏⽤户验证,这样的场景往往存在于⽀持单点登录功能的多个联合平台中,如天猫和淘宝), 这时就需要在发送请求时在请求头中注意:
这⾥的OPTION⽅法中应该设置响应状态码为 204 是为了告知客户端表⽰该响应成功了,但是该响应并没有返回任何响应体,如果状态码为 200,还得携带多余的响应体,在这
django登录注册功能
种场景下是完全多余的,只会浪费流量。
三.这⾥只是实现了单个视图⽀持跨域请求,要实现全局⽀持跨域请求请点击:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论