Django框架中处理 CORS和 跨域请求问题详解

首页 » Python » Django框架中处理 CORS和 跨域请求问题详解

浏览器的同源策略

由于浏览器存在同源策略机制(Same origin policy),同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接受罢了。

同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

浏览器同源策略并不是对所有的请求均制约:

  • 制约: XmlHttpRequest
  • 不制约: img、iframe、script等具有src属性的标签

跨域,跨域名访问,如:http://www.c1.com 域名向 http://www.c2.com域名发送请求。

也就是说请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同。如果不相同就会出现跨域请求,那么浏览器就会进行拦截并在控制台输出信息:同源策略禁止读取位于 http://127.0.0.1:8001/SendAjax/ 的远程资源。(原因:CORS 头缺少 ‘Access-Control-Allow-Origin’,这里可参考一个案例:Django框架中JSONP跨域请求的本质以及解决方式

浏览器的CORS简介

随着技术的发展,现在的浏览器可以支持主动设置从而允许跨域请求,即:跨域资源共享(CORS,Cross-Origin Resource Sharing),其本质是设置响应头,使得浏览器允许跨域请求。如果不做响应头处理,那么默认响应头信息为:X-Content-Type-Options: nosniff,浏览器如果检索到nosniff指令,那么拒绝,具体规则如下:

  • 对于css文件:如果通过 styleSheet 参考检索到的响应中接收到 “nosniff” 指令,则 浏览器 不会加载“stylesheet”文件,除非 MIME 类型匹配 “text/css”。
  • 对于js文件:如果通过 script 参考检索到的响应中接收到 “nosniff” 指令,则 浏览器不会加载”script”文件,除非 MIME 类型匹配以下值之一:
  • “application/ecmascript” 或 “application/javascript” 或 “application/x-javascript” 或 “text/ecmascript” 或 “text/javascript” 或 “text/jscript” 或 “text/x-javascript” 或 “text/vbs” 或 “text/vbscript”

这里可参考一个案例:Django框架中JSONP跨域请求的本质以及解决方式

CORS基本流程

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段。

浏览器发出CORS非简单请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

CORS两种请求详解

只要同时满足以下两大条件,就属于简单请求。

(1)请求方法是HEAD、GET、 POST其中质疑
(2)HTTP的头信息不超出以下几种字段:

Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

凡是不同时满足上面两个条件,就属于非简单请求。浏览器对这两种请求的处理,是不一样的。

Django项目中支持CORS

在返回的结果中加入允许信息(简单请求)

def test(request):
    import json
    obj = HttpResponse(json.dumps({'name': 'lqz'}))
    # obj['Access-Control-Allow-Origin']='*'
    obj['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8004'
    return obj

放到中间件处理复杂和简单请求:

from django.utils.deprecation import MiddlewareMixin

class CorsMiddleWare(MiddlewareMixin):
    def process_response(self, request, response):
        if request.method == "OPTIONS":
            # 可以加*
            response["Access-Control-Allow-Headers"] = "Content-Type"
            response["Access-Control-Allow-Origin"] = "http://localhost:8080"
        return response

这里可参考一个案例:Django框架中JSONP跨域请求的本质以及解决方式

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《Django框架中处理 CORS和 跨域请求问题详解》 发布于2020-05-04

分享到:
赞(0) 赏杯咖啡

评论 抢沙发

9 + 3 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册