Restful规范
-
协议
尽量使用HTTPs协议 -
域名
两种方式:
https://api.example.com要解决跨域问题,jsonp,cros,nginx代理
https://example.org/api常用的方式
-
版本
应该将api的版本号放在url中,方便迭代。 -
面向资源,网络上全是资源
所以url中不能有动词 -
method:http动词
–get
–post
–put
–patch
–delete
对应了查,增,改,小改,删。还有不常用的head(获取资源的元数据)和options(获取信息,关于信息哪些属性时客户端可以改变的) -
过滤信息
常用的过滤信息就是,分页,按照什么排序 -
状态码和code
常见的状态码:
200:请求成功; 201新建或者修改数据成功; 202 一个请求已经进入排队; 204 用户删除数据成功; 401 用户权限不足 403 访问禁止 404 请求的数据不存在 ; 410 :请求的资源被永久删除; 500 内部服务器错误。
code自定义:
{ ’ 1000 ': ‘error’ }
-
错误处理
返回错误信息
{ error:"不存在的api接口" }
-
返回结果
针对不同分http动作,返回结果,需要对对象进行序列化然后返回 -
Hypermedia API
例子:
用户访问/order 可得到所有订单
[
{
id :1
name :'the'
},
{
id :2
name :'he'
}
]
用户访问/order/1可获得id为1的订单的详细信息
{
id : 1
name:'the'
count:9
price:199
}
现在这种方式就是不友好的,下面这中有一个连接,就是友好的。
[
{
id :1
name :'the'
url:'https://www.example.com/order/1'
},
{
id :2
name :'he'
url:'https://www.example.com/order/1'
}
]
跨域问题?
浏览器有同源策略限制预防csrf攻击
:当协议不同,域名不同,端口不同时会出现跨域问题。
- jsonp实现:只能解决get请求
// οnclick="kk()"
function kk() {
$.ajax({
url: 'http://127.0.0.1:8000/session',
type: 'get',
dataType: 'jsonp', // 请求方式为jsonp
jsonp: 'callback',
jsonpCallback: "handleCallback", // 自定义回调函数名
data: {
'k1':'v1'},
});
}
});
function handleCallback() {
alert('dsada')
//dosomething
}
其中:jsonp
和jsonpCallback
是一组键值对,后端通过jsonp的值获取到回调函数的名字,而jsonpCallback的值是定义的回调函数的名字。data是向后端传输的数据,后端通过键取值,即通过get(‘k2’)可以得到’v2’
# 假设访问的地址通过url找到Session类。
class Session(View):
def get(self,request,*args,**kwargs):
fun = request.GET.get('callback')
# print(request.GET.get('callback')) 回调函数的名字 handleCallback
# print(request.GET.get('k1')) 传入的值v2
content = f'{fun}()' # 构建函数 content = handleCallback()
return HttpResponse(content) # 会执行前端页面中的handleCallback()函数
- 通过cors实现
- 安装:
pip install django-cors-headers
- 注册app:
INSTALLED_APPS = [ ... 'corsheaders', ... ]
- 加中间件:需要再csrf中间件前面
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
# 'django.middleware.common.CommonMiddleware',
...
]
- 指定origin:量少的时候
CORS_ORIGIN_WHITELIST = [
"https://example.com",
"https://sub.example.com",
"http://localhost:8080",
"http://127.0.0.1:9000"
]
# CORS_ORIGIN_ALLOW_ALL = True # 允许所有源地址的请求:不应该是True
大量的ip
CORS_ORIGIN_REGEX_WHITELIST = [
r"^https://\w+\.example\.com$",
]
- 允许的方法,下面是默认的。
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
- 允许的headers,下面是默认的。
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
更多内容:Github:django-cors-headers
- 通过Nginx实现跨域。通过代理的方式,在nginx中不存在同源策略。
DRF的使用
1. 认证
- 自定义认证类
class Authentication(BaseAuthentication):
'''自定义的认证类'''
def authenticate(self, request):
pass # 具体认证逻辑
'''
auth = request.META.get('HTTP_AUTH',None) # type: str
# 然后对auth切片,解码操作,回去user对象和认证信息,并作为元组返回
# return (user,token)
'''
- 在视图类views中作为局部配置
class OrderView(APIView):
authentication_classes = [Authentication,] # 局部引用
- 在settings中全局配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':['app1.utils.auth.Authentication',],
'UNAUTHENTICATED_USER':None, # 默认匿名用户配置
# 'UNAUTHENTICATED_USER':lambda :"匿名用户", # 不如上面的好用,直接判断None
'UNAUTHENTICATED_TOKEN':None, # 默认匿名用户的auth<