刨析Django----跨域corsheaders
目录前后端分离同源与跨域Django配置跨域请求应用案例前后端分离待更新同源与跨域Django配置跨域请求应用案例前后端分离的Django与Vue交互,实现用户的注册功能。
前后端分离
前端服务器,返回页面、样式等
后端服务器,返回数据。
同源与跨域
浏览器的同源策略,
协议、地址、端口号均相同,即为同源;
否则为非同源,即跨域
简单请求(simple request)
- 请求方法为GET/POST/HEAD
- 请求头有Accept/Accept-Language/Content-Language/Content-Type
且Content-Type值(application/x-www-form-urlencoded; multipart/form-data;text/plain)
同时满足以上要求的才是简单请求;否则为预检请求(preflight request),即复杂请求
简单请求的头部中有Origin,若允许跨域,则响应头中有Access-Control-Allow-Origin,
允许请求携带Cookie,则响应头中有Access-Control-Allow-Credentials
预检请求,流程:
-
先发送OPTIONS请求,请求头
Origin
Access-Control-Request-Method
Access-Control-Request-Headers
针对OPTIONS的响应,头部有:
Access-Control-Allow-Origin 允许跨域
Access-Control-Allow-Methods 允许跨域的方法
Access-Control-Allow-Headers 允许跨域的请求头
Access-Control-Allow-Credentials 允许携带Cookie -
主请求, POST or …
两步走太麻烦,响应头中加入Access-Control-Max-Age,设置OPTIONS请求的缓存时间,在此期间不再发送OPTIONS请求。
响应头中有set-cookie,但是浏览器中却没有存储
前端使用Vue+axios直接跨域请求django,响应头中有set-cookie,但是浏览器应用中cookie没有存储。
解决:配置Vue代理
在Vue项目的根目录
创建一个vue.config.js配置文件,启动项目时,自动加载该配置文件。
//vue.config.js
module.exports = {
devServer:{
proxy:'http://127.0.0.1:8000'
}
}
然后所有的请求都会被vue代理到http://127.0.0.1:8000。
注意需重启vue项目
暂存问题:
-
删除session, 浏览器的sessionid不会删除,但可以实现退出功能的效果;
httpOnly=True,防止js读取cookie,提高cookie的安全性,降低XSS(跨站脚本攻击)的攻击的风险res.set_cookie(key,value,max_age,httpOnly=True) -
delete_cookie,浏览器无效果,可以set_cookie设置1s过期解决无法删除的问题。
Django配置跨域请求
只需在Django服务端,简单配置
- 安装django-cors-headers
#安装第三方应用
pip3 install django-cors-headers
- 配置django>settings.py
INSTALLED_APPS = [
...,
'corsheaders',
'rest_framework',
]
MIDDLEWARES = [
...,
'corsheaders.middleware.CorsMiddleware', #注意在common的上方,官方建议
'django.middleware.common.CommonMiddleware','
]
#允许前端请求携带Cookie(含sessionid)
CORS_ALLOW_CREDENTIALS = True #会话保持必须
# CORS_ORIGIN_ALLOW_ALL = True #允许所有的源跨域到django
CORS_ORIGIN_WHITELIST = (
'http://127.0.0.1:5000', #格式严格
) #[]也可以
#非必须
CORS_ALLOW_METHODS = (
"GET",
"POST",
"PUT",
"DELETE",
'OPTIONS'
'PATCH',
'VIEW'
)
#非必须
CORS_ALLOW_HEADERS = (
"XMLHttpRequest",
'token',
'X_FILENAME',
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)
#暴露响应头,xhr才可以拿到响应头
CORS_EXPOSE_HEADERS = (
'token',
)
#缓存options请求
CORS_PREFLIGHT_MAX_AGE = 86400 #秒
应用案例
前后端分离的方式,实现基于Django的用户的注册功能。
需求分析
- 基于Flask搭建前端服务器,用户发送GET请求,返回注册页面。
- 基于Django搭建后端服务器,用户提交注册数据,后端接收并保存用户数据。
- UI界面如下:
概要设计
- 整体架构图
pending - 技术选择
Django长期支持版,
2.2----->最新补丁版本2.2.25
3.2----->最新补丁版3.2.10
官网建议更新到最新的补丁版
#win 更新
python -m pip install django==3.2.10 -i https://pypi.tuna.tsinghua.edu.cn/simple/
#以上通过-i 使用清华源
#linux
sudo pip3 install django==2.2.25 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
这里采用:
Ubuntu1804
python_3.6
Django_2.2.25
Flask_1.1.2
mysql_5.7
redis
详细设计
GET http://localhost:5000/user/register/
前端服务器返回register.html页面
POST http://localhost:8000/user/register/
后端接收并保存用户的注册数据,若用户已存在,则返回响应‘用户名已注册’;否则返回响应 ‘注册OK’
数据库设计
这里后端需要有一个数据库及表 来存储用户的注册数据。
采用mysql数据库,连接mysql服务,创建一个数据库(如lauf),然后在Django中配置mysql即可。
表设计
编码实现
- 搭建前后端的虚拟环境
#安装虚拟环境模块
sudo apt-get install python3-venv #失败多试几次
#创建前端虚拟环境
python3 -m venv frontenv
cd frontenv/bin
source ./activate #激活虚拟环境
pip install flask==1.1.2 #pip list/ pip freeze 查看安装的包
#创建后端虚拟环境
python3 -m venv backenv
然后将虚拟环境移动到~/.virtualenvs,便于在开发环境中使用。
-
搭建前端服务器
使用vscode处理前端服务,并配置frontenv虚拟环境,配置方法参考flask框架介绍
链接:代码参考
提取码:97t5 -
搭建后端服务器
使用pycharm处理后端服务,并配置backenv虚拟环境
链接:代码参考
提取码:306t
遇到的问题
- 跨域没有配置好
- 未禁用csrf中间件
- 返回的不是Json响应
- 服务端未启动
更多推荐
所有评论(0)