rest framework、cors、this、中间件、请求、7层协议
1. django请求生命周期
-> 执行遵循wsgi协议的模块(socket服务端) -> 中间件(路由匹配) -> 视图函数(业务处理:ORM、模板渲染) -> 中间件 -> wsgi返回
- wsgi, 他就是socket服务端,用于接收用户请求并将请求进行初次封装,然后将请求交给web框架(Flask、Django) - 中间件,帮助我们对请求进行校验或在请求对象中添加其他相关数据,例如:csrf、request.session - 路由匹配 - 视图函数,在视图函数中进行业务逻辑的处理,可能涉及到:orm、templates => 渲染 - 中间件,对响应的数据进行处理。 - wsgi,将响应的内容发送给浏览器。
2. 什么wsgi
web服务网关接口 实现该协议的模块: - wsgiref - werkzurg - uwsig
3. FBV CBV
- FBV FBV(function base views) 就是在视图里使用函数处理请求 - CBV CBV(class base views) 就是在视图里使用类处理请求。
优缺点:
Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:
- 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
- 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
4. djang rest framework作用、对django rest framework 框架得认识
帮我们做符合restful规范的接口的!
绑定在django上的一个组件,提供一些功能。
快速搭建基于restful规范的接口。
快速搭建API接口 怎么学得呀!! 首先看官方文档;比较重要,前后端分离得项目,公司要用; 看源码去了!! 路由: 可以通过as_view传参;根据请求方式不同执行相应得方法; 视图: 帮助开发者提供一些类,并在类中提供了多个方法供我们使用 版本: 在url中设置version参数,用户请求时候传入参数,在request.version获取版本, 根据版本不同做不同得处理。 认证: 写一个类并注册到认证类。其中有一个authticate方法编写认证得逻辑,拿用户得token,验证是否存在 认证成功:(user,auth) 认证失败: raise AuthticateFailed(..) None - 匿名用户; 权限: 写一个类注册到权限类,在类得has_permission方法中编写认证逻辑 True False 频率限制: 写一个类注册到频率类,在类得allow_request/wait方法编写认证逻辑 allow_request true false 如果返回false,那么就要执行wait 解析器: 根据content_type请求头,选择不同得解析器 对请求体得数据进行解析 content_type = url-encode user=alex&age=12 content_type = application/json {user:alex,age:12} 分页: 对从数据库中获取到得数据进行分页处理:sql - > limit offset - 根据页码;http://www.luffycity.com/api/v1/student/?page=1&size=10 - 根据索引:http://www.luffycity.com/api/v1/student/?offset=60&limit=10 - 根据加密: http://www.luffycity.com/api/v1/student/?page=erdsc 赠送:页码越大速度越慢,为什么以及如何解决? 原因:页码越大向后需要扫描得行数越多,因为每次都是从0开始得。 解决: - 限制显示得页数 - 记录当前页数据ID最大值和最小值,再次分页时,利用where根据ID先进行筛选,然后再分页。 序列化: 对queryset序列化以及对请求数据格式校验 渲染器: 根据url中传入得后缀,决定数据如何渲染到页面上。
5. restful 规范(10)
什么是接口? - URL - 约束 # 约束继承(实现)了他的类中必须含有IFoo中的方法 interface IFoo: def func(self): pass class Foo(IFoo): def func(self): print(11111) 1. 根据method不同,进行不同操作 GET/POST/PUT/DELETE/PATCH 2. 面向资源编程 http://www.luffycity.com/salary 3. 体现版本 http://www.luffycity.com/v1/salary http://www.luffycity.com/v2/salary https://v4.bootcss.com/ https://v3.bootcss.com/ 4. 体现是API http://www.luffycity.com/api/v1/salary http://www.luffycity.com/api/v2/salary http://api.luffycity.com/v1/salary http://api.luffycity.com/v2/salary 5. https https://www.luffycity.com/api/v1/salary https://www.luffycity.com/api/v2/salary 6. 响应式设置状态码 200 300 400 500 return HttpResponse('adfasdf',status=300) 7. 条件 https://www.luffycity.com/api/v2/salary?page=1&size=10 8. 返回值 https://www.luffycity.com/api/v2/salary GET: 所有列表 { code: 10000, data: [ {'id':1,'title':'高亮'}, {'id':1,'title':'龙泰'}, {'id':1,'title':'小东北'}, ] } POST: 返回新增的数据 {'id':1,'title':'高亮'} https://www.luffycity.com/api/v2/salary/1/ GET: 获取单条数据 {'id':1,'title':'高亮'} PUT:更新 {'id':1,'title':'高亮'} PATCH: 局部更新 {'id':1,'title':'高亮'} DELETE:删除 9. 返回错误信息 { code: 100001, error: 'xxx错误' } 10. Hypermedia API ret = { code: 1000, data:{ id:1, name:'小强', depart_id:http://www.luffycity.com/api/v1/depart/8/ } } 建议大家使用restful规范
你理解的 restful 规范? restful是一个规范,规定API如何编写,通过他可以让我们api更加简洁可维护。 如,最直观的: method: - get - post - put - delete 原来都是url中设置的。 除此之外: - api - 版本 - 名词 - 条件 - 状态码 - 返回值 - 错误信息 - hypermedia link
6. django rest framework框架组件(10)
- 权限 - 认证 - 访问频率限制 - 序列化 - 路由 - 视图 面试题:你的写的类都继承过哪些类? class View(object): class APIView(View): class GenericAPIView(views.APIView): class GenericViewSet(ViewSetMixin, generics.GenericAPIView) class ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet): - 分页 - 解析器 - 渲染器 - 版本
7. 跨域
- 为什么会有跨域? - 绕过浏览器同源策略就可以跨域。 - jsonp 动态创建script标签 同源策略会阻止ajax请求;不阻止具有src属性的标签 <script src='xxxx'></script> - cors 设置响应头
1. 为什么会有跨域? 浏览器具有同源策略所有才出现跨域。 同源策略: - 开放:src - 禁止:ajax 解决跨域: - jsonp,在客户端动态创建一个script标签 1.客户端:创建一个 <script src='http://www.jxntv.cn/data/jmd-jxtv2.html'></script> <script> function func(arg){ alert(arg); } </script> 2.服务端:接收到请求并处理并返回值 "func('success')" 相当于: <script> func('success') </script> PS: jsonp只能发送GET请求 - cors,设置响应响应响应响应响应头 - 简单请求 - 复杂请求 - options请求做预检 - PUT/POST.... 在django中解决方案: - 中间件中设置响应头 - django中的一个第三方组件:cors 补充: jQuery Ajax: $.ajax({ ... }) 原生Ajax:XMLHttpRequest对象: var xhr = new XMLHttpRequest() xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 已经接收到全部响应数据,执行以下操作 var data = xhr.responseText; console.log(data); } }; xhr.open('POST', "/test/", true); // 设置请求头 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); // 发送请求 xhr.send('n1=1;n2=2;');
8. this
题目1: var name = '景女神' function Foo(name,age){ this.name = name; this.age = age; this.getName = function(){ console.log(this.name); # 文州 (function(){ console.log(this.name); # 女神 })() } } obj = new Foo('文州',19) obj.getName() 题目2: var name = '景女神' function Foo(name,age){ this.name = name; this.age = age; this.getName = function(){ console.log(this.name); # 文州 var that = this (function(){ console.log(that.name); # 文州 })() } } obj = new Foo('文州',19) obj.getName() 题目3: var name = '景女神' obj = { name:'文州', age: 19, getName:function(){ console.log(this.name); # 文州 var that = this (function(){ console.log(that.name); # 文州 })() } } obj.getName()
9. 你理解的Http协议?
- 建立在tcp之上 - 一次请求一次响应然后断开连接(无状态、短连接) - 请求和响应 发送:请求头\r\n\r\n请求体 host:www.luffy.com\r\ncontent-type:application/json\r\n\r\n请求体 响应:响应头\r\n\r\n响应体 ...
Http协议就是一个传输数据格式。 我原来学习django框架,从socket服务端开始学起。 自己创造了一个socket服务器来充当:网站。 浏览器当socket客户端。 更清楚的明白到底http协议是什么? - 请求头 请求体 - 响应头 响应体 一次请求响应后,断开连接。
10. django中间件是什么?
中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作。
11. 使用中间件做过什么?
- 内置 - csrf - session - 自定义 - 登录认证 - 权限 - cors 跨域
- 应用场景: - 登录认证,不再需要在每个函数中添加装饰器 - 权限,当用户登录时候获取当前用户所有权限并放入session,然后再次访问其他页面,获取当前url并在session中进行匹配。如果没有匹配成功,则在中间件返回“无权访问” 权限的表,。。字段呢 - 跨域,设置响应头 - jsonp,动态创建一个script标签。只能发get请求; - cors,设置响应头 应用:本地开发前后端分离项目的时使用。
12 . 中间件中有多少个方法?
5个
process_request
process_response
process_view
process_exception
process_template_response(用的比较少)
13. 视图常见的继承
from rest_framework.views import APIView # * from rest_framework.generics import GenericAPIView from rest_framework.viewsets import GenericViewSet # as_view from rest_framework.viewsets import ModelViewSet # *
14. 如何实现的访问频率控制?
匿名用户:无法控制,因为用户可以换代理IP { 192.168.1.1:[1521223123.232, 1521223122.232, 1521223121.232], 192.168.1.2:[1521223123.232, 1521223122.232, 1521223121.232], 192.168.1.3:[1521223123.232, 1521223122.232, 1521223121.232], 192.168.1.4:[1521223123.232, 1521223122.232, 1521223121.232], 192.168.1.5:[1521223123.232, 1521223122.232, 1521223121.232], 192.168.1.6:[1521223123.232, 1521223122.232, 1521223121.232], } 登录用户:如果有很多账号,也无法限制 { alex:[1521223123.232, 1521223122.232, 1521223121.232], eric:[1521223123.232, 1521223122.232, 1521223121.232], } 参考源码:from rest_framework.throttling import SimpleRateThrottle
15. 常见的请求头
- Content-Type json / url-encode / . - User-Agent 请求得设备 - referer 可以做图片防盗链。 - Host 当前得域名 - cookies
16. 常见的请求方法
- GET/POST/DELETE/PUT/PATCH/OPTIONS
17. 常见的请求体
Form表单提交: POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\nusername=alex&password=123&... Ajax请求: POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\nusername=alex&password=123&... POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\n{“username”:"alex","password":123} 补充:django中获取请求体 - request.POST - request.body
18. 常见的状态码
- 200 - 301/302 临时重定向 永久重定向 - 403/404 服务器禁止访问,服务器没有找到文件 - 500/502
19. OSI 7层模型,3次握手,4次挥手
OSI七层: 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 TCP/IP四层/五层: 应用层 应用层 :软件 qq 暴风 传输层 传输层 :建立端口到端口的通信 0-65535 0-1023为系统占用端口 tcp ucp 网络层 网络层 :ip+mac 能找到全世界唯一的计算机 ip:找到哪一个局域网 mac:找到那一台机器 数据链路层 接口层 :定义电信号的分组方式 物理层 :发送01010101...电信号 基于tcp协议通信,为何建立链接需要三次握手,而断开链接却需要四次挥手 三次握手:client请求,server同意请求,client同意 四次挥手:client请求,server同意,server请求,client同意 因为:server有可能还有数据要发送 为何基于tcp协议的通信比基于udp协议的通信更可靠? tcp:可靠 对方给了确认收到信息,才发下一个,如果没收到确认信息就重发 udp:不可靠 一直发数据,不需要对方回应