当前位置: 代码网 > it编程>前端脚本>Python > Django解决CORS跨域问题的方案

Django解决CORS跨域问题的方案

2024年05月19日 Python 我要评论
产生跨域问题的原因cross-origin resource sharing(cors) 跨域问题,在前后端后离项目,selenium , playweight 自动化测试代码中经常遇到。 而使用 p

产生跨域问题的原因

cross-origin resource sharing(cors) 跨域问题,在前后端后离项目,selenium , playweight 自动化测试代码中经常遇到。 而使用 python request, curl, postman 等非浏览器代码发送请求时则不存在这个问题。

浏览器采用了同源保护策略,为了防御恶意攻击,会检查request消息与response消息的域名 domain与端口 port,如果不相同,则表示响应消息与请求消息不是同源,可能是伪造的响应消息,因此浏览器添加了cors限制功能,默认不接受非同源的响应消息。

浏览器与服务器都运行在同一台电脑上为何仍出现跨域问题?

原因: ajax脚本在本机浏览器运行时, 默认主机地址为http://127.0.0.1:8848,而开发环境 django服务默认地址为:http://localhost:8000 上,因此,浏览器与服务器虽然主机名相同,但端口不同,所以不符合cors要求,故浏览器仍然会出现cors错误。

解决思路

如何解决这种情形的问题呢?

浏览器同源策略有条规则,response头部如果包含如下字段值,则不做cors检查。

access-control-allow-origin: *

接下来就是如何添加这个参数。 方法通常有2种:
(1) 方法1: 在使用前端代理在response中添加access-control-allow-origin:头部参数;
(2) 方法2:在服务器端,给response添加access-control-allow-origin头部参数。

方法1,实施还是比较麻烦,前端还要安装node.js的服务代理程序才能实现。而方法2,如果服务器使用django,则实现很容易。即通过中间件middleware 对所有response添加、修改头部参数。

解决方法1: 通过自定义中间件修改response头部

在myproject/myapp/ 目录下,新建1个 middlewares.py 文件

class corsmiddleware(object):
    """中间件:跨域访问"""
    def __init__(self, get_response):
        self.get_response = get_response
    
    def __call__(self, request):
        return self.get_response(request)
    
    # process_template_response(), process_response() 只能二选一、根据view的response类型,重载相应方法。 
    def process_template_response(self,request,response):
        # 如果view 使用了render渲染response,使用这个中间件
        response["access-control-allow-origin"] = "*"
        return response
        
    def process_response(self,request,response):
        # 如果view使用httpresponse, 将使用这个中间件
        response["access-control-allow-origin"] = "*"
        return response

这个类的方法 process_template_response(), process_response(),用于为每个django response添加1个access-control-allow-origin: * 头部参数, 两个方法使用1个就可以。 当然也可以利用这个中间件添加、修改其它头部参数。

将新定义的中间件 corsmiddleware 添加到 settings.py 的 middleware classes:的列表,如 ajax使用的主机+端口号,如:http://127.0.0.1:8848

middleware = [
    'django.middleware.security.securitymiddleware',
    'django.contrib.sessions.middleware.sessionmiddleware',
    'django.middleware.common.commonmiddleware',
    'django.middleware.csrf.csrfviewmiddleware',
    'django.contrib.auth.middleware.authenticationmiddleware',
    'django.contrib.messages.middleware.messagemiddleware',
    'django.middleware.clickjacking.xframeoptionsmiddleware',
    'myapp.middlewares.corsmiddleware',  # 允许跨域访问中间件
]

再次发送ajax请求,可以成功接收到django的响应数据。使用浏览器devtools检查response响应头部参数,可以看到已经添加了access-control-allow-origin: *

http/1.1 200 ok
date: sat, 21 aug 2023 08:26:17 gmt
server: wsgiserver/0.2 cpython/3.11.4
content-type: text/html; charset=utf-8
access-control-allow-origin: *
x-frame-options: deny
content-length: 5177
vary: cookie
x-content-type-options: nosniff
referrer-policy: same-origin

说明: 此方法虽然简单易行,access-control-allow-origin 设置为*, 允许任何跨域访问,显然不太安全,每次修改须更新代码,因此仅适用于开发测试环境。

解决方法2: 通过 django-cors-headers 库来实现

生产环境下,建议通过第3方库django-cors-headers 来实现,其步骤如下

1) 安装

pip install django-cors-headers

2) 修改 settings.py 配置文件

添加到应用列表

installed_apps = (
    ##...
    'corsheaders'
)

添加中间件列表 corsheaders.middleware.corsmiddleware

middleware = [
    'django.middleware.security.securitymiddleware',
    'django.contrib.sessions.middleware.sessionmiddleware',
    'django.middleware.common.commonmiddleware',
    'django.middleware.csrf.csrfviewmiddleware',
    'corsheaders.middleware.corsmiddleware',
    ......

然后,添加下面配置 允许所有 domain 访问

cors_origin_allow_all = true

或者,允许某些域访问

cors_origin_allow_all = false
# 允许域名加入白名单
cors_origin_whitelist = (
    'http//:localhost:8000',
)

说明

在测试环境中,可以允许所有domain来访问,以避免 cors问题,前后端分离项目在生产环境下,通常应该部署在同域下,如果确实需要跨域,则将前端域名添加到白名单 cors_origin_whitelist配置项中,禁止其它域访问。

最后

以上就是django解决cors跨域问题的方案的详细内容,更多关于django解决cors跨域的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com