我们已经学到了中间件的三个方法:process_request、process_respond 和 process_view:
process_request 在路由分发之前被调用,用来处理请求的数据;
process_respond 在gwsi相应之前进行一些处理;
process_view 在路由分发之后,进入视图函数之前执行。
此外,中间件还有两个方法,process_exception 和 porcess_remplate_response:
其基本用法为:
from django.shortcuts import redirect,HttpResponse,render
from django.utils.deprecation import MiddlewareMixin
class MD1(MiddlewareMixin):
def process_request(self,request):
print('MD1--process_request')
def process_response(self, request,response):
print('MD1--process_response')
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print('MD1---',view_func.__name__)
# 视图有错误,执行中间件的process_exception方法,没错不执行
def process_exception(self, request, exception):
print('MD1:process_exception',exception)
def process_template_response(self, request, response):
print("MD1 中的process_template_response")
return response
class MD2(MiddlewareMixin):
def process_request(self, request):
print('MD2--process_request')
def process_response(self, request, response):
print('MD2--process_response')
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print('MD2---',view_func.__name__)
def process_exception(self, request, exception):
print('MD2:process_exception',exception)
def process_template_response(self, request, response):
print("MD2 中的process_template_response")
return response
重写响应对象中render方法的示例:
def index(request):
def render():
print('index函数内部的render')
return HttpResponse('xxxx')
ret = HttpResponse('ok')
ret.render = render
return ret
中间件的执行顺序大致是这样的:
$('#btn').click(function () {
var uname = $('[type="text"]').val();
var pwd = $('[type="password"]').val();
var csrf_token = $('[name="csrfmiddlewaretoken"]').val();
$.ajax({
url:'/login/',
type:'post',
// data:{uname:uname,pwd:pwd,csrfmiddlewaretoken:csrf_token},
headers:{'X-CSRFToken':$.cookie('csrftoken')}, // 设置请求头:
data:{uname:uname,pwd:pwd,},
success:function (res) {
console.log(res);
}
})
})
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。攻击者通过 HTTP 请求江数据传送到服务器,从而盗取回话的 cookie。盗取回话 cookie 之后,攻击者不仅可以获取用户的信息,还可以修改该 cookie 关联的账户信息。
所以解决 CSRF 攻击的最直接的办法就是生成一个随机的 csrftoken 值,保存在用户的页面上,每次请求都带着这个值过来完成校验。
$('#btn').click(function () {
var uname = $('[type="text"]').val();
var pwd = $('[type="password"]').val();
var csrf_token = $('[name="csrfmiddlewaretoken"]').val();
$.cookie('xx','sss'); // 设置cookie
$.ajax({
url:'/login/',
type:'post',
// data:{uname:uname,pwd:pwd,csrfmiddlewaretoken:csrf_token},
headers:{'X-CSRFToken':$.cookie('csrftoken')},
data:{uname:uname,pwd:pwd,},
success:function (res) {
console.log(res);
}
})
})
form 组件主要有三个用途:
使用步骤:
1 创建form类
from django import forms
class LoginForm(forms.Form):
# username = request.POST.get('username')
# if '--' in username:
# raise
# {'username':'xxxx','password':''}
username = forms.CharField(
label='用户名:',
required=True, #不 能为空
max_length=7, # 长度不能超过7个字符
min_length=2, # 最短不能低于2个字符
# initial='张三', #初始值
widget=forms.TextInput(attrs={'class':'c1','placeholder':'请输入用户名'}),
error_messages={
'required':'不能为空',
'max_length':'太长了,难受!',
'min_length':'太短了,更难受!',
},
)
password = forms.CharField(
required=True,
label='密码:',
widget=forms.PasswordInput(attrs={'class':'c1','placeholder':'请输入密码'},render_value=True), # render_value=True让密码输入的数据保留
)
sex = forms.ChoiceField(
choices=[(1,'男'),(2,'女')],
widget=forms.RadioSelect(attrs={'xx':'none'}),
)
2 在views中实例化这个类对象,并交给前端 html 页面
def login(request):
if request.method == 'GET':
form_obj = LoginForm()
return render(request,'login.html', {'form_obj':form_obj})
else:
form_obj = LoginForm(request.POST)
# 准备校验,也就是检查不符合格式的部分,并且保存到列表中,写成伪代码为:
# form_obj
# username:alexxxxxx -- form_obj.username.errors.append('太长了!!')
# username:alexxxxxx -- form_obj.username.errors.append('包含了--!feifa zifu')
# password form_obj.password.errors.append('太长了!!')
print(status)
return render(request,'login.html', {'form_obj':form_obj})
3 进行数据格式校验
form_obj = LoginForm(request.POST)
status = form_obj.is_valid() # 开始校验,上面的伪代码Django已经封装好,直接使用即可
print(status)
return render(request,'login.html', {'form_obj':form_obj})
在前端页面中,可以写成这样:
<form action="" method="post" novalidate>
{% csrf_token %}
<div>
<label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}label>
{{ form_obj.username }}
<span>{{ form_obj.username.errors.0 }}span>
div>
<div>
<label for="{{ form_obj.password.id_for_label }}">{{ form_obj.password.label }}label>
{{ form_obj.password }}
<span>{{ form_obj.password.errors.0 }}span>
div>
<input type="submit">
<div>
<label for="{{ form_obj.sex.id_for_label }}">{{ form_obj.sex.label }}label>
{{ form_obj.sex }}
div>
form>