达达博客项目-学习笔记,B站达内项目实战
前后端分离优点:
1.各司其职前端:视觉层面,兼容性,前端性能优化后端:高并发,高可用,性能
2.解耦,前端后端均易于扩展
3.后端灵活搭配各类前端
4.提高用户体验
5.并行开发,提高开发效率http无状态?-token
如何解决跨域问题?-CORS
解决csrf问题?-token
动态静态资源分离?-CDN(内容网络分发)
跨域:
flask默认5000端口, 向前端服务器发送请求后,通过ajax往django8000端口获取数据,违背了浏览器的同源策略-----涉及到跨域
跨域解决方案
cross-origin resource sharing CORS跨域资源共享
允许浏览器向跨域源服务器发出请求,克服ajax只能同源使用的限制特点:1.浏览器自动完成2.服务器需要支持原理:一 简单请求满足以下条件的请求为简单请求,否则为复杂请求1.请求方法如下GET or HEAD or POST2.请求头仅包含AcceptAccept-LanguageContent-LanguageContent-Type3.Content-Type仅支持application/x-www-form-urlencodedmultipart/form-datatext/plain简单请求跨域流程:1.请求头仅包含请求头中携带Origin,该字段表明自己来自那个域2.响应如果请求头中的Origin在服务器接受范围内,则返回以下响应头Access-Control-Allow-Origin 服务器接收的域Access-Control-Allow-Gredentials 是否接受CookieAccess-Control-Expose-Headers 如果需要获取其他头,需要在此指定二 复杂请求or预检请求,跨域流程1.先发OPTIONS请求,携带如下请求头Origin 表明此请求来自哪个域Access-Control-Request-Method 此次请求使用的方法Access-Control-Request-Headers 此次请求使用的头2.响应服务器开始评估返回以下响应头Access-Control-Allow-Origin 服务器接收的域Access-Control-Allow-Methods 服务器接受的跨域请求方法Access-Control-Allow-Headers 所有支持的头部Access-Control-Allow-Gredentials 是否接受CookieAccess-Control-Max-Age OPTION 请求缓存时间,单位s3.主请求阶段Origin 表明此请求来自哪个域4.主请求相应阶段Access-Control-Allow-Origin 服务器接收的域配置CORS配置流程:1,INSTALLED_APPS 中添加 corsheaders2,MIDDLEWARE 中添加 corsheaders.middleware.CorsMiddleware位置尽量靠前,官方建议 ‘django.middleware.common.CommonMiddleware’ 上方3,CORS_ORIGIN_ALLOW_ALL 布尔值 如果为True 白名单不启用 (34互斥,4为白名单列表)4,CORS_ORIGIN_WHITERLIST = ['https://example.com'](预检请求的真实请求方法)5, CORS_ALLOW_METHODS = ('DELETE','GET','OPTIONS','PATCH','POST','PUT',)6, CORS_ALLOW_HEADERS = ('accept-encoding','authorization','content-type','dnt','origin','user-agent','x-csrftoken','x-requested-with',)7,CORS_PREFLIGHT_MAX_AGE 默认 86400s8,CORS_EXPOSE_HEADERS [] (希望ajax能获取到的头信息)9,CORS_ALLOW_CREDENTIALS 布尔值,默认False (COOKIE信息)
RESTful设计风格
全称:Representational State Transfer
1、资源(Resources)网络上的一个实体,或者说是网络上的一个具体信息,并且每个资源都有独一无二的URI与之对应,获取资源=直接访问URI
2、表现层(Representation)如何去表现资源,即资源的表现形式,如HTML,XML,JPG,MP3,JSON等
3.状态转化(State Transfer)访问一个URI即发生了一次 客户端和服务端的交互;此次交互将会涉及到数据和状态的变化客户端需要通过某些方法触发具体的变化 - HTTP method 如GET,POST,PUT等等
特征:1、每一个URI代表一种资源2、客户端和服务端之间传递着资源的某种表现形式3、客户端通过HTTP的几个动作 对 资源进行操作 - 发生 ‘状态转化’设计原则1.协议- http/https2.域名:域名中体现出api的字样,如https://api.example.com or https://example.org/api/3.版本:https://api.example.com/v1/4.路径路径中避免使用动词,资源用名词表示https://api.example.com/v1/users5.HTTP动词语义GET:SELECT 从服务器中取出资源 一项或多项POST:CREATE 在服务器中新建一个资源PUT: UPDATE在服务器中更新资源(客户端提供改变后的完整资源)PATCH: UPDATE在服务器中更新资源(客户端提供改变的属性)DELETE:DELETE 从服务器中删除资源6.巧用查询字符串?limit=10:指定返回数量?offset=10:指定返回的开始位置?page=2&per_page=100:指定第几页,以及每页的数量7.状态码(1)HTTP响应码表达此次请求的结果(2)自定义内部code进行响应返回结构如下{'code': 200,'data':{},'error':xxx }8.返回结果(实际中还是根据业务来设计)根据HTTP动作不同,返回结果的结构也有所不同
用户系统-ORM
产品经理 — API文档 具体在达内给的API文档附件中
会话状态保持
Cookies存在浏览器 session存在服务器上
都不是太好的方案
cookie数据串改和session存储压力在cookie上添加数据校验,保证数据未被串改是最优解---利用jwtjwt前传---base64
b64encode 将输入的参数转化为base64规则的串
b64decode 将base64串解密为明文
urlsafe_b64encode 作用与b64encode作用相同,但是会将 + 替换成 - 将 / 替换成 _
urlsafe_b64decode 同上HMAC-SHA256
通过一种特别的计算方式之后产生的消息认证码,使用三列算法同时结合一个加密秘钥。用来保证数据的完整性,同时可以用来做某个消息的身份验证。
自定义一个key 结合明文 生成一个密钥JWT --- json-web-token
为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准,JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便从资源服务器获取资源
三部分b' 第一部分 . 第二部分 . 第三部分 '第一部分header格式为字典,元数据格式如下{ 'alg' : 'HS256', 'typ':'JWT' }alg : 算法HS256 : HMAC-SHA256typ : token类别,此处必须大写JWT该部分数据转成json串,并用base64转码得到第一部分
第二部分pay-load格式为字典- 此部分分为公有声明与私有声明公有声明 : JWT提供了内置关键字用于描述常见的问题,此部分均为可选项,用户根据自己需求 按需添加key,如:{'exp' : xxx,# Expiration Time 此token的过期时间和时间戳'iss' : xxx,# (issuer) Claim 指明token的签发者'iat' : xxx, # (Issued At) Claim 指明此创建时间的时间戳'aud' : xxx,# (Audience) Claim 指明此token签发面向群体}私有声明 : 用户根据自己的业务需求添加自定义的key{'username' : 'cs'}
第三部分 signature---签名根据haeder中的alg确定具体算法HS256(自定义的key,base64后的header +‘.’+base64后的payload)JWT检验规则
1,解析header,确认alg
2,签名校验 - 根据传过来的header和payload按照alg指定的算法进行签名,将签名结果和传过来的sign进行对比,对比一致则校验通过
3,获取payload自定义内容代码层面,python
pip3 install pyjwt
encode(payload,key,algorithm)
decode(jwt,key,algorithm)
import jwt
code = jwt.encode({'username': 'cs'}, 'cs123456', algorithm='HS256')
print(code)
# eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImNzIn0.J8vGzKLldkRZpT6KIXi-9kw2-WoaGJody9Qyg6BH5d8import jwt
code = jwt.encode({'username': 'cs'}, 'cs123456', algorithm='HS256')
content = jwt.decode(code, 'cs123456', algorithms='HS256')
print(content)
# {'username': 'cs'}
特殊说明
如果在encode的时候payload添加了exp字段,exp字段需要当前时间戳+此token的有效时间,
在执行decode的时候,若检查到了exp字段,且token过期,则抛出jwt.ExpiredSignatureError
import jwt
import timecode = jwt.encode({'username': 'cs', 'exp': time.time() + 3}, 'cs123456', algorithm='HS256')
print(code)
time.sleep(5)
content = jwt.decode(code, 'cs123456', algorithms='HS256')
print(content)
# ERROR: jwt.exceptions.ExpiredSignatureError: Signature has expired
前后端分离场景下,使用JWT
原则:1,JWT签发后,交由浏览器保存2,浏览器可将其存储在‘本地存储’中(防止cookie遭受CSRF攻击,本地存储不会自动提交,需要手动提交)3,需要 用户登录 才能使用的功能,前端ajax中需要将jwt传至后端;可放在请求头中发送## 第三方短信平台
需要接入其他平台,让平台帮忙发短信,该服务通常是有偿服务
容联云服务
给URL发Http请求
python接入容联云发短信
celery
sudo pip3 install celery
发短信需要请求第三方平台,若第三方平台出现问题,服务器也将出现卡顿。
采用生产者消费者模型,提高项目的可扩展性,横向拓展,保障业务的能正常运行,降低阻塞的可能性生产者 put -> 队列 -> get 消费者
![celery](https://img-blog.csdnimg.cn/bbfb65c3253d40e882b8120ee2db25d2.png#pic_center)celery是一个简单,灵活可靠的,处理大量消息的分布式系统
它专注于实时处理任务的,同时也支持任务调度 ,RQ,redis
broker - 消息传输的中间件,生产者一旦有消息发送,将发至broker;
backend - 用于存储消息/任务结果,如果需要跟踪和查询任务状态,则需要添加相关配置
worker - 工作者 执行broker中的消息/任务的进程如何判断是否采用celery
1.是否可能产生阻塞
2.请求需要的响应是否实时,快速
# 使用 -- 难点:worker如何进行处理
from celery import Celery
app = Celery('cs',broker='redis://password@127.0.0.1:6379/0')# 创建任务函数
@app.task
def task_test():print('task is running...')
# 启动worker
# ubuntu终端中,tasks.py 文件的同级目录下执行
# celery -A tasks worker --loglevel = info# 此模式默认为前台启动,终端中会输出相关日志# 生产者调用
from tasks import task_test
task_test.delay() # 推送至消息队列中,由消费者执行# worker前台
[2022-07-26 12:44:54,244: INFO/MainProcess] Task tasks.task_test[01f2f6b8-1b3a-40db-b308-559b381987e0] received
[2022-07-26 12:44:54,247: WARNING/ForkPoolWorker-8] test is runing
[2022-07-26 12:44:54,249: INFO/ForkPoolWorker-8] Task tasks.task_test[01f2f6b8-1b3a-40db-b308-559b381987e0] succeeded in 0.002011182999922312s: None# 存储执行结果-worker
from celery import Celery
app = Celery('cs', broker='redis://:@127.0.0.1:6379/1', backend='redis://:@127.0.0.1:6379/2')@app.task
def task_test(a, b):print('test is runing')return a + b# worker执行的返回值会作为结果自动存入到backend中from tasks import task_testtask_test.delay('cs', 'nb')# worker前台显示
[2022-07-26 13:02:20,273: INFO/MainProcess] Task tasks.task_test[ecb1b515-b62e-468a-be3c-af40a550ac65] received
[2022-07-26 13:02:20,274: WARNING/ForkPoolWorker-8] test is runing
[2022-07-26 13:02:20,279: INFO/ForkPoolWorker-8] Task tasks.task_test[ecb1b515-b62e-468a-be3c-af40a550ac65] succeeded in 0.004370476000076451s: 'csnb'# redis库中
127.0.0.1:6379[2]> keys *
1) "celery-task-meta-2516cdbb-0aa4-4e17-a96e-a2ed28774964"
127.0.0.1:6379[2]> get "celery-task-meta-2516cdbb-0aa4-4e17-a96e-a2ed28774964"
"{\"status\": \"SUCCESS\", \"result\": \"csnb\", \"traceback\": null, \"children\": [], \"date_done\": \"2022-07-26T05:04:45.279617\", \"task_id\": \"2516cdbb-0aa4-4e17-a96e-a2ed28774964\"}"
django中使用celery
# 在settings同级目录中,创建celery.py编写初始化代码
from celery import Celery
from django.conf import settings
import osos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dadablog.settings')app = Celery('dadablog')app.conf.update(broker_url='redis://:@127.0.0.1:6379/1'
)# 自动到settings中已注册的app中寻找worker函数
app.autodiscover_tasks(settings.INSTALLED_APPS)# 在对应的应用中创建tasks.py,编写worker函数
from django.conf import settings
from tools.sms import YunTongXin
from dadablog.celery import app@app.task
def send_sms_c(phone, code):yun = YunTongXin(**settings.YUN_CONFIG)res = yun.run(phone, code)return res# 在视图函数中需要生产的时候,使用worker函数.delay()代替直接调用
# 发送验证码
# send_sms(phone, code)
send_sms_c.delay(phone,code)# 进入manage.py同名目录下 启动celery服务celery -A dadablog worker -l info
# celery自动寻找到worker函数
[tasks]. user.tasks.send_sms_c
# 并且提示在django环境下,DEBUG=True会出现内存泄露,所以在正式项目中,必须设置为false
正式环境后台启动celery
nohup celery -A proj worker -P gencent -c 1000 > celery.log 2>&1 &
nohup:忽略所有挂断(SIGHUB)信号
&:表示命令在后台执行
celery默认是开多进程,在python中,用协程并发厉害点,可以用-P参数 gevent开启协程运行celery -c 指定具体的协程数量
> celery.log 就是将命令的输出放入.log文件中,在哪执行命令,.log文件就生成在哪
> 2代表标准错误输出,1代表标准输出, 2>&1 就是将错误输出重定向给标准输出
> 意思就是在这个celery.log文件中 不仅有正常输出,还有报错信息等输出
达达博客项目-学习笔记,B站达内项目实战相关推荐
- 瑞吉外卖项目学习笔记-P20-Linux系统环境下项目部署
P20-Linux系统环境下项目部署 1.Linux系统环境软件安装 2.项目部署-手工部署项目(繁琐,效率低下) 2.1在IDEA中开发SpringBoot项目,并打包成jar包 2.2将jar包上 ...
- spring boot 前后端分离项目(商城项目)学习笔记
spring boot 前后端分离项目(商城项目)学习笔记 目录 spring boot 前后端分离项目(商城项目)学习笔记 后端配置 springboot项目 pom.xml文件 maven 配置文 ...
- Stanford CS230吴恩达Reading Research Papers学习笔记
目录 Stanford CS230吴恩达Reading Research Papers学习笔记 如何通过更有效地阅读研究论文,来接触新领域知识 如何有效地针对一篇论文进行阅读 论文的多次阅读法 阅读论 ...
- Redis学习笔记(B站狂神说)(自己总结方便复习)
Redis学习笔记B站狂神说 redis: 非关系型数据库 一.NoSQL概述 1.为什么要用Nosql 1.单机Mysql的年代 思考一下,这种情况下:整个网站的瓶颈是什么? 1.数据量如果太大,一 ...
- 尚医通项目学习笔记Part1
尚医通项目学习笔记 前言 一.目前学习进度 二.学习记录 1.项目简介 1.1 项目所会用到的技术栈 1.2 业务流程 2.项目学习笔记 2.1MyBatis-Plus相关 2.2搭建项目框架 2.3 ...
- [学习笔记]B站视频:磨剑之作,七周成“师”!【七周成为数据分析师】- 第一周
[学习笔记]B站学习视频:七周成为数据分析师-第一周 序 数据思维 结构化 公式化 业务化 数据分析的思维技巧 象限法 多维法 假设法 指数法 二八法 对比法 漏斗法 如何在业务时间锻炼数据分析思维 ...
- 笔记 | 吴恩达Coursera Deep Learning学习笔记
向AI转型的程序员都关注了这个号☝☝☝ 作者:Lisa Song 微软总部云智能高级数据科学家,现居西雅图.具有多年机器学习和深度学习的应用经验,熟悉各种业务场景下机器学习和人工智能产品的需求分析.架 ...
- TheBeerHouse 网站项目学习笔记(5)---架构设计
前述讨论: TheBeerHouse 网站项目学习笔记(1)----换肤技术 TheBeerHouse 网站项目学习笔记(2)----个性化管理 ...
- 吴恩达《机器学习》学习笔记十四——应用机器学习的建议实现一个机器学习模型的改进
吴恩达<机器学习>学习笔记十四--应用机器学习的建议实现一个机器学习模型的改进 一.任务介绍 二.代码实现 1.准备数据 2.代价函数 3.梯度计算 4.带有正则化的代价函数和梯度计算 5 ...
- 吴恩达《机器学习》学习笔记十二——机器学习系统
吴恩达<机器学习>学习笔记十二--机器学习系统 一.设计机器学习系统的思想 1.快速实现+绘制学习曲线--寻找重点优化的方向 2.误差分析 3.数值估计 二.偏斜类问题(类别不均衡) 三. ...
最新文章
- 算法(第4版)Algorithms, Fourth Edition
- 大牛整理:java去掉字符串中的逗号
- BZOJ1082: [SCOI2005]栅栏
- Android之解决打补丁包后移动端为什么不升级,升级之后出现“应用未安装“,以及更新成功之后反复更新问题
- oracle system用户创建job 其他用户,oracle创建表空间、用户和表以及sys和system的区别...
- 20169210《Linux内核原理与分析》第十二周作业
- 数组名与指向数组的指针之间的联系与区别【数据结构】
- 44.Android之Shape设置虚线、圆角和渐变学习
- 【ThinkingInC++】66、pointer Stash的使用
- MsChart5 累计柱状图 分类统计
- Column name pattern can not be NULL or empty.
- 开源,不是一种道德绑架
- mysql_safe作用_mysqld_safe
- Django 实现用户认证set_Cookie
- Python 中Python 为什么要继承 object 类
- robocode 安装 使用
- 涩会:大学学历——办理居住证的具体流程(深圳)
- table表格标签css固定最后一列方案
- java 省市联动_省市联动(json)
- 数据结构与算法(python):图(Graph)的基本概念及应用