0627内容:
上节回顾: 1. FBV、CBV 2. 数据库操作 class UserGroup(models.Model): """ 部门 3 """ title = models.CharField(max_length=32) class UserInfo(models.Model): """ 员工4 """ nid = models.BigAutoField(primary_key=True) user = models.CharField(max_length=32) password = models.CharField(max_length=64) age = models.IntegerField(default=1) # ug_id 1 ug = models.ForeignKey("UserGroup",null=True) - 跨表 正: 1. q = UserInfo.objects.all().first() q.ug.title 2. UserInfo.objects.values('nid','ug_id') UserInfo.objects.values('nid','ug_id','ug__title') 3. UserInfo.objects.values_list('nid','ug_id','ug__title') 反: 1. 小写的表名_set obj = UserGroup.objects.all().first() result = obj.userinfo_set.all() [userinfo对象,userinfo对象,] 2. 小写的表名 v = UserGroup.objects.values('id','title') v = UserGroup.objects.values('id','title','小写的表名称') v = UserGroup.objects.values('id','title','小写的表名称__age') 3. 小写的表名 v = UserGroup.objects.values_list('id','title') v = UserGroup.objects.values_list('id','title','小写的表名称') v = UserGroup.objects.values_list('id','title','小写的表名称__age') PS: 前面的所有数据都会显示 - 其他: UserInfo.objects.all() UserInfo.objects.filter(id=1,id=2) UserInfo.objects.all().first() UserInfo.objects.all().count() UserInfo.objects.all().update() UserInfo.objects.all().delete() UserInfo.objects.all()[1:19] 跨表: 正向: xxxx.filter(ut__title='超级用户').values('id','name','ut__title') 反向: xxxx.filter(表名称__title='超级用户').values('id','name','表名称__title') 3. 分页组件 - 内置 - 自定义
1. Django ORM操作 # 1.增删改查 # 2. 一般: # models.UserInfo.objects.filter(id__gt=1) # models.UserInfo.objects.filter(id__lt=1) # models.UserInfo.objects.filter(id__lte=1) # models.UserInfo.objects.filter(id__gte=1) # models.UserInfo.objects.filter(id__in=[1,2,3]) # models.UserInfo.objects.filter(id__range=[1,2]) # models.UserInfo.objects.filter(name__startswith='xxxx') # models.UserInfo.objects.filter(name__contains='xxxx') # models.UserInfo.objects.exclude(id=1) # 3. 排序 user_list = models.UserInfo.objects.all().order_by('-id','name') # 4. 分组 from django.db.models import Count,Sum,Max,Min # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')) # print(v.query) # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) # print(v.query) # v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) # print(v.query) # 5. F,更新时用于获取原来的值 # from django.db.models import F,Q # models.UserInfo.objects.all().update(age=F("age")+1) # 6. Q,用于构造复杂查询条件 # 应用一: # models.UserInfo.objects.filter(Q(id__gt=1)) # models.UserInfo.objects.filter(Q(id=8) | Q(id=2)) # models.UserInfo.objects.filter(Q(id=8) & Q(id=2)) # 应用二: # q1 = Q() # q1.connector = 'OR' # q1.children.append(('id__gt', 1)) # q1.children.append(('id', 10)) # q1.children.append(('id', 9)) # # # q2 = Q() # q2.connector = 'OR' # q2.children.append(('c1', 1)) # q2.children.append(('c1', 10)) # q2.children.append(('c1', 9)) # # q3 = Q() # q3.connector = 'AND' # q3.children.append(('id', 1)) # q3.children.append(('id', 2)) # q2.add(q3,'OR') # # con = Q() # con.add(q1, 'AND') # con.add(q2, 'AND') # models.UserInfo.objects.filter(con) # 7. extra, 额外查询条件以及相关表,排序 models.UserInfo.objects.filter(id__gt=1) models.UserInfo.objects.all() # id name age ut_id models.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None) # a. 映射 # select # select_params=None # select 此处 from 表 # b. 条件 # where=None # params=None, # select * from 表 where 此处 # c. 表 # tables # select * from 表,此处 # c. 排序 # order_by=None # select * from 表 order by 此处 models.UserInfo.objects.extra( select={'newid':'select count(1) from app01_usertype where id>%s'}, select_params=[1,], where = ['age>%s'], params=[18,], order_by=['-age'], tables=['app01_usertype'] ) """ select app01_userinfo.id, (select count(1) from app01_usertype where id>1) as newid from app01_userinfo,app01_usertype where app01_userinfo.age > 18 order by app01_userinfo.age desc """ result = models.UserInfo.objects.filter(id__gt=1).extra( where=['app01_userinfo.id < %s'], params=[100,], tables=['app01_usertype'], order_by=['-app01_userinfo.id'], select={'uid':1,'sw':"select count(1) from app01_userinfo"} ) print(result.query) # SELECT (1) AS "uid", (select count(1) from app01_userinfo) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" FROM "app01_userinfo" , "app01_usertype" WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) ORDER BY ("app01_userinfo".id) DESC # 8. 原生SQL语句 from django.db import connection, connections cursor = connection.cursor() # connection=default数据 cursor = connections['db2'].cursor() cursor.execute("""SELECT * from auth_user where id = %s""", [1]) row = cursor.fetchone() row = cursor.fetchall() - extra - 原生SQL语句 - raw result = models.UserInfo.objects.raw('select * from userinfo') [obj(UserInfo),obj,] result = models.UserInfo.objects.raw('select id,1 as name,2 as age,4 as ut_id from usertype') [obj(UserInfo),obj,] v1 = models.UserInfo.objects.raw('SELECT id,title FROM app01_usertype',translations=name_map) # 9. 简单的操作 http://www.cnblogs.com/wupeiqi/articles/6216618.html
2. xss攻击 - 慎用 safe和mark_safe - 非要用,一定要过滤关键字
XSS攻击:
"""djangoxss URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^comment/', views.comment), #输入内容 url(r'^index/', views.index), #查看内容 url(r'^test/', views.test), #测试页 ]
from django.shortcuts import render from django.utils.safestring import mark_safe # Create your views here. msg = [] def comment(request): if request.method == "GET": return render(request,'comment.html') else: v = request.POST.get('content') if "script" in v: return render(request,'comment.html',{'error':'小比崽子还黑我'}) else: msg.append(v) return render(request,'comment.html') def index(request): return render(request,'index.html',{'msg':msg}) def test(request): temp = "<a href='http://www.baidu.com'>百度</a>" newtemp = mark_safe(temp) # return render(request,'test.html',{'temp':temp}) return render(request,'test.html',{'temp':newtemp})
template文件(html)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form method="POST" action="/comment/"> <input type="text" name="content" /> <input type="submit" value="提交" />{{ error }} </form> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>评论</h1> {% for item in msg %} <div>{{ item|safe }}</div> #加上safe代表标记提交的数据时安全的 {% endfor %} </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> {{ temp|safe }} </body> </html>
xss总结:
XSS注入攻击(跨站脚本攻击) for(var i=0,j=0;i<999,j<9999;i++,j++) { window.alert(""); } <html> <head>text</head> <body> <form> <input type="text" name="text"> </form> </body> </html> <script> alert('sb') </script> <script> 获取本地cookie,将cookie发送至www.xxx.com(黑客的网址,把本地的隐私cookie发送给黑客) </script> <h1>评论</h1> {% for item in msg %} <div>{{ item|safe }}</div> {% endfor %} 写上safe会出问题 safe是别人能随便添加或者随便写的,一定要对特殊字符做过滤 <script>alert('sb')</script> 会弹出一个框,如果是循环会撑爆浏览器
标记某个字符串或者标签是安全的:
两种方式:
1.前端页面的字符串{{ temp|safe}}加上 |safe
2.from django.utils.safestring import mark_safe
def test(request):
temp = "<a href='http://www.baidu.com'>百度</a>"
newtemp = mark_safe(temp)
# return render(request,'test.html',{'temp':temp})
return render(request,'test.html',{'temp':newtemp})
xss攻击:
慎用safe和mark_safe
非要用,一定要在提交数据时过滤关键字
上节回顾: 1. FBV、CBV 2. 数据库操作 class UserGroup(models.Model): """ 部门 3 """ title = models.CharField(max_length=32) class UserInfo(models.Model): """ 员工4 """ nid = models.BigAutoField(primary_key=True) user = models.CharField(max_length=32) password = models.CharField(max_length=64) age = models.IntegerField(default=1) # ug_id 1 ug = models.ForeignKey("UserGroup",null=True) - 跨表 正: 1. q = UserInfo.objects.all().first() q.ug.title 2. UserInfo.objects.values('nid','ug_id') UserInfo.objects.values('nid','ug_id','ug__title') 3. UserInfo.objects.values_list('nid','ug_id','ug__title') 反: 1. 小写的表名_set obj = UserGroup.objects.all().first() result = obj.userinfo_set.all() [userinfo对象,userinfo对象,] 2. 小写的表名 v = UserGroup.objects.values('id','title') v = UserGroup.objects.values('id','title','小写的表名称') v = UserGroup.objects.values('id','title','小写的表名称__age') 3. 小写的表名 v = UserGroup.objects.values_list('id','title') v = UserGroup.objects.values_list('id','title','小写的表名称') v = UserGroup.objects.values_list('id','title','小写的表名称__age') PS: 前面的所有数据都会显示 - 其他: UserInfo.objects.all() UserInfo.objects.filter(id=1,id=2) UserInfo.objects.all().first() UserInfo.objects.all().count() UserInfo.objects.all().update() UserInfo.objects.all().delete() UserInfo.objects.all()[1:19] 跨表: 正向: xxxx.filter(ut__title='超级用户').values('id','name','ut__title') 反向: xxxx.filter(表名称__title='超级用户').values('id','name','表名称__title') 3. 分页组件 - 内置 - 自定义
今日任务: 1. Django ORM操作 # 1.增删改查 # 2. 一般: # models.UserInfo.objects.filter(id__gt=1) # models.UserInfo.objects.filter(id__lt=1) # models.UserInfo.objects.filter(id__lte=1) # models.UserInfo.objects.filter(id__gte=1) # models.UserInfo.objects.filter(id__in=[1,2,3]) # models.UserInfo.objects.filter(id__range=[1,2]) # models.UserInfo.objects.filter(name__startswith='xxxx') # models.UserInfo.objects.filter(name__contains='xxxx') # models.UserInfo.objects.exclude(id=1) # 3. 排序 user_list = models.UserInfo.objects.all().order_by('-id','name') # 4. 分组 from django.db.models import Count,Sum,Max,Min # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')) # print(v.query) # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) # print(v.query) # v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) # print(v.query) # 5. F,更新时用于获取原来的值 # from django.db.models import F,Q # models.UserInfo.objects.all().update(age=F("age")+1) # 6. Q,用于构造复杂查询条件 # 应用一: # models.UserInfo.objects.filter(Q(id__gt=1)) # models.UserInfo.objects.filter(Q(id=8) | Q(id=2)) # models.UserInfo.objects.filter(Q(id=8) & Q(id=2)) # 应用二: # q1 = Q() # q1.connector = 'OR' # q1.children.append(('id__gt', 1)) # q1.children.append(('id', 10)) # q1.children.append(('id', 9)) # # # q2 = Q() # q2.connector = 'OR' # q2.children.append(('c1', 1)) # q2.children.append(('c1', 10)) # q2.children.append(('c1', 9)) # # q3 = Q() # q3.connector = 'AND' # q3.children.append(('id', 1)) # q3.children.append(('id', 2)) # q2.add(q3,'OR') # # con = Q() # con.add(q1, 'AND') # con.add(q2, 'AND') # models.UserInfo.objects.filter(con) # 7. extra, 额外查询条件以及相关表,排序 models.UserInfo.objects.filter(id__gt=1) models.UserInfo.objects.all() # id name age ut_id models.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None) # a. 映射 # select # select_params=None # select 此处 from 表 # b. 条件 # where=None # params=None, # select * from 表 where 此处 # c. 表 # tables # select * from 表,此处 # c. 排序 # order_by=None # select * from 表 order by 此处 models.UserInfo.objects.extra( select={'newid':'select count(1) from app01_usertype where id>%s'}, select_params=[1,], where = ['age>%s'], params=[18,], order_by=['-age'], tables=['app01_usertype'] ) """ select app01_userinfo.id, (select count(1) from app01_usertype where id>1) as newid from app01_userinfo,app01_usertype where app01_userinfo.age > 18 order by app01_userinfo.age desc """ result = models.UserInfo.objects.filter(id__gt=1).extra( where=['app01_userinfo.id < %s'], params=[100,], tables=['app01_usertype'], order_by=['-app01_userinfo.id'], select={'uid':1,'sw':"select count(1) from app01_userinfo"} ) print(result.query) # SELECT (1) AS "uid", (select count(1) from app01_userinfo) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" FROM "app01_userinfo" , "app01_usertype" WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) ORDER BY ("app01_userinfo".id) DESC # 8. 原生SQL语句 from django.db import connection, connections cursor = connection.cursor() # connection=default数据 cursor = connections['db2'].cursor() cursor.execute("""SELECT * from auth_user where id = %s""", [1]) row = cursor.fetchone() row = cursor.fetchall() - extra - 原生SQL语句 - raw result = models.UserInfo.objects.raw('select * from userinfo') [obj(UserInfo),obj,] result = models.UserInfo.objects.raw('select id,1 as name,2 as age,4 as ut_id from usertype') [obj(UserInfo),obj,] v1 = models.UserInfo.objects.raw('SELECT id,title FROM app01_usertype',translations=name_map) # 9. 简单的操作 http://www.cnblogs.com/wupeiqi/articles/6216618.html 2. xss攻击 - 慎用 safe和mark_safe - 非要用,一定要过滤关键字 3. CSRF 4. 模板引擎 - 部分方法 - 自定义方法
1.手动创建第三张关系表:
#多对多关系 class Boy(models.Model): name = models.CharField(max_length=32) class Girl(models.Model): nick = models.CharField(max_length=32) class Love(models.Model): b = models.ForeignKey('Boy') g = models.ForeignKey('Girl') class Meta: unique_together = [ ('b','g'),#联合唯一索引,女孩和男孩只能约会一次 ] 注释掉Love表,然后运行python manage.py makemigrations和python manage.py migrate 会删除第三张表
往三张表插入数据插入数据,
#多对多 objs = [ models.Boy(name='方少伟'), models.Boy(name='游勤兵'), models.Boy(name='陈涛'), models.Boy(name='闫龙'), models.Boy(name='吴彦祖'), ] models.Boy.objects.bulk_create(objs,5) #批量插入数据,5条提交一次 objss = [ models.Girl(nick='张俭会'), models.Girl(nick='周明月'), models.Girl(nick='小猫'), models.Girl(nick='小狗'), ] models.Girl.objects.bulk_create(objss,5) #批量插入数据,5条提交一次 models.Love.objects.create(b_id=1,g_id=3) models.Love.objects.create(b_id=1,g_id=4) models.Love.objects.create(b_id=2,g_id=1) models.Love.objects.create(b_id=2,g_id=2)
from django.shortcuts import render,HttpResponse,redirect from django.views import View from app01 import models from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage from django.db.models import F,Q from django.db.models import Count,Min,Max,Sum from django.db import connection,connections # Create your views here. def test(request): # #多对多 # objs = [ # models.Boy(name='方少伟'), # models.Boy(name='游勤兵'), # models.Boy(name='陈涛'), # models.Boy(name='闫龙'), # models.Boy(name='吴彦祖'), # ] # models.Boy.objects.bulk_create(objs,5) # objss = [ # models.Girl(nick='张俭会'), # models.Girl(nick='周明月'), # models.Girl(nick='小猫'), # models.Girl(nick='小狗'), # ] # models.Girl.objects.bulk_create(objss,5) # # models.Love.objects.create(b_id=1,g_id=3) # models.Love.objects.create(b_id=1,g_id=4) # models.Love.objects.create(b_id=2,g_id=1) # models.Love.objects.create(b_id=2,g_id=2) # 1.查询和方少伟有染的姑娘:反向操作,连表 obj = models.Boy.objects.filter(name='方少伟').first() love_list = obj.love_set.all() print(love_list)#<QuerySet [<Love: Love object>, <Love: Love object>]> for row in love_list: print(row.g.nick) #2第二种方法: 正向操作,连表 love_list=models.Love.objects.filter(b__name='方少伟') for row in love_list: print(row.g.nick) #3 第三种方法: 正向操作,连表 字典 love_list=models.Love.objects.filter(b__name='方少伟').values('g__nick') print(love_list)#<QuerySet [{'g__nick': '小猫'}, {'g__nick': '小狗'}]> for row in love_list: print(row['g__nick']) return HttpResponse('ok')#小猫 小狗 # 4 第四种方法: 正向操作,连表 元组 love_list=models.Love.objects.filter(b__name='方少伟').values_list('g__nick') print(love_list)#<QuerySet [('小猫',), ('小狗',)]> for row in love_list: print(row[0])#小猫 小狗 # 5 第五种方法: 正向操作,连表 元组 love_list=models.Love.objects.filter(b__name='方少伟').select_related('g') print(love_list)#<QuerySet [<Love: Love object>, <Love: Love object>]> for obj in love_list: print(obj.g.nick)#小猫 小狗 return HttpResponse('ok')
2.自动创建第三张表,如下图所示
#多对多关系 class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField('Girl') class Girl(models.Model): nick = models.CharField(max_length=32) # m = models.ManyToManyField('Boy')
#多对多关系 class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField('Girl') class Girl(models.Model): nick = models.CharField(max_length=32) # m = models.ManyToManyField('Boy') class Love(models.Model): b = models.ForeignKey('Boy') g = models.ForeignKey('Girl') class Meta: unique_together = [ ('b','g'),#联合唯一索引,女孩和男孩只能约会一次 ] 这里会生成四张表,因为models.ManyToManyField字段会生成第三张表,Love是第四张表
#多对多关系 class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g')) class Girl(models.Model): nick = models.CharField(max_length=32) # m = models.ManyToManyField('Boy') class Love(models.Model): b = models.ForeignKey('Boy') g = models.ForeignKey('Girl') class Meta: unique_together = [ ('b','g'),#联合唯一索引,女孩和男孩只能约会一次 ] 加了个through和through_fields参数
CSRF HTML设置成:{{ csrf_token }}打开网页链接http://127.0.0.1:8000/csrf1.html,会生成下图的画面,不会生成input框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form method="POST" action="/csrf1.html"> loAUyDKmKdviy4p2L5fn2A7FbdhllrC7ThgUpJ8K697z97WhLc4PJDyPWBmObuEH <input type="text" name="user"> <input type="submit" name="提交"> </form> </body> </html>
CSRF HTML设置成:{% csrf_token %} 打开网页链接http://127.0.0.1:8000/csrf1.html,会生成下图的画面
提交之后返回字符串ok
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form method="POST" action="/csrf1.html"> <input type='hidden' name='csrfmiddlewaretoken' value='82DbgE3R8Q7Q8oPXcDYhOhqlJQ6pco9MGVjb7KrfuMJ7JrmccKNJvkRvuebS2rbm' /> <input type="text" name="user"> <input type="submit" name="提交"> </form> </body> </html>
这个图也会看到csrftoken随机字符串
github登录页面输入框也会有这个token随机字符串
加上一个装饰器,会局部禁用,但是前提是全站使用CSRF TOKEN验证
from django.views.decorators.csrf import csrf_exempt @csrf_exempt def csrf1(request): if request.method == "GET": return render(request,'csrf1.html') else: return HttpResponse('ok')
全局禁用CSRF TOKEN验证,局部使用CSRF TOKEN验证,加上这个装饰器@csrf_protect
from django.views.decorators.csrf import csrf_exempt,csrf_protect # @csrf_exempt @csrf_protect def csrf1(request): if request.method == "GET": return render(request,'csrf1.html') else: return HttpResponse('ok')
以上是FBV的内容
CBV
Django之CSRF(Ajax请求):
有两种方式:
第一种方式(csrftoken放在data里):
<form method="POST" action="/csrf1.html"> {% csrf_token %} {# {{ csrf_token }}#} <input id="user" type="text" name="user"> <input type="submit" name="提交"> <a onclick="submitForm();">Ajax提交</a> </form> <script src="/static/jquery-1.12.4.js"></script> <script src="/static/jquery.cookie.js"></script> <script> function submitForm() { var csrf = $('input[name="csrfmiddlewaretoken"]').val(); var user = $('#user').val(); $.ajax({ url:'/csrf1.html', type:'POST', data:{'user':user,'csrfmiddlewaretoken':csrf}, success:function(arg) { console.log(arg); } }) } </script>
'csrfmiddlewaretoken':csrf如果没加这个键值对
这样ajax提交数据 会提示403
浏览器控制台输入如下命令获取csrftoken
document.cookie
"csrftoken=eIFRre9gheSzcS6X0FPxYAFIX1kzUcLjMBlRikxEDauQNVDc0MEZFD6SIpp2KfNT"
获取这样的键值对,根据"="分割
可以通过导入<script src="/static/jquery.cookie.js"></script>
可以自动切片
运行这个命令也可以取值(csrftoken)
$.cookie('csrftoken')
"eIFRre9gheSzcS6X0FPxYAFIX1kzUcLjMBlRikxEDauQNVDc0MEZFD6SIpp2KfNT"
cookie还可以自己设置值
$.cookie('sgadgvhf','999999999999999999999')
"sgadgvhf=999999999999999999999"
document.cookie
"csrftoken=eIFRre9gheSzcS6X0FPxYAFIX1kzUcLjMBlRikxEDauQNVDc0MEZFD6SIpp2KfNT; sgadgvhf=999999999999999999999"
第二种方式:(csrftoken放在请求头里)
先拿到token:var token = $.cookie('csrftoken'); 再加一个请求头headers:{'X-CSRFToken':token}。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form method="POST" action="/csrf1.html"> {% csrf_token %} {# {{ csrf_token }}#} <input id="user" type="text" name="user"> <input type="submit" name="提交"> <a onclick="submitForm();">Ajax提交</a> </form> <script src="/static/jquery-1.12.4.js"></script> <script src="/static/jquery.cookie.js"></script> <script> function submitForm() { var token = $.cookie('csrftoken'); var user = $('#user').val(); $.ajax({ url:'/csrf1.html', type:'POST', headers:{'X-CSRFToken':token}, data:{'user':user}, success:function(arg) { console.log(arg); } }) } </script> </body> </html>