基于cookie的登录认证装饰器

      def check_login(f):
def inner(request,*args,**kwargs):
is_login = request.COOKIES.get('is_login')
if is_login == 'True':
ret = f(request)
return ret
else:
return redirect('login')
return inner @check_login
def cart(request):
return render(request,'cart.html')

基于session的登录认证装饰器

      def check_login(f):
def inner(request,*args,**kwargs):
is_login = request.session.get('is_login')
if is_login:
ret = f(request,*args,**kwargs)
return ret
else:
return redirect('login')
return inner @check_login
def cart(request):
return render(request,'cart.html')

sweetalert插件完成ajax删除数据动作

局部刷新页面进行删除 参考图书管理系统基于ajax请求删除数据

sweetalert基于bootstrap,所有首先要先导入bootstrap插件,然后把sweetalert下载下来,一般前端开发人员会把插件放在dist文件夹里面,所有我们只要用dist文件夹里面的插件就可以了,其他的都不要
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'bootstrap-sweetalert-master/dist/sweetalert.css' %}"> //sweetalert插件css
</head>
<body> <button class="btn btn-danger">删除啦</button> </body>
<script src="{% static 'jquery.js' %}"></script>
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<script src="{% static 'bootstrap-sweetalert-master/dist/sweetalert.min.js' %}"></script> //sweetalert插件js </html>
      $('.del').on('click',function(){
var delete_id = $(this).prev().text() //获取上一个标签的id
var ths = $(this); //因为下面的函数中this指向的不是我们的标签按钮,所以通过一个全部变量来保存一下这个$(this),方便后面使用
swal({ //这个sweetalert内部源码 直接拿来用就行,修改下文本内容
title:'are you sure?',
text:'要谨慎!',
type:'warning',
showCancalButton:true,
confirmButtonClass:'btn-danger',
confirmButtonText:'确定删除',
cancelButtonText:'容我三思',
closeOnConfirm:false
},
//点击确认删除时触发的函数
function(){
$.ajax({//路径拼接相当于/ajax_delete_book/1/
url:'/ajax_delete_book/'+delete_id+'/',
type:'get',
success:function(res){
console.log(res);
if (res==='ok'){
//关闭弹窗
swal('删除成功!','你可以准备跑路了!','success');//这个是swal自带的方法
//局部刷新,删除对应记录
ths.parent().parent().remove();
}
}
})
}
)
})

js中的箭头函数

      普通函数:var k = function(参数){return 'kkk'};
箭头函数:var k =(参数) =>{return 'kkkk'};
箭头函数简写:var k = (参数) => 'kkkk'

js函数中this的指向问题,面试题

  • 1.箭头函数 会去寻找上下文的this
      var a = 'xx';
var d1 = {
a:'ss',
f:()=>{
//this指向函数调用者
console.log(this.a); //xx
},
}
d1.f() #调用者是d1对象,但是里面是箭头函数,所以会去往d1对象上面寻找,即window对象,所以打印的内容为xx
  • 2.函数的单体模式
      var a = 'xx';
var d1 = {
a:'ss',
f(){
console.log(this.a);
},
}
d1.f() #调用者是d1对象,打印结果为ss
  • 3.没有对象调用,那么this指向的就是window对象

var a = 'xx';
var d1 = {
a:'ss',
f:function(){
console.log(this.a); //ss
function f1(){
console.log(this);//指向了window对象
console.log(this.a);//结果为xx
}
f1()
},
}
d1.f()
  • 4.箭头函数,改变this的指向,将this指向上下文的this
      var a = 'xx';
var d1 = {
a:'ss',
f:function(){
console.log(this.a); //ss
var f1 = ()=>{
console.log(this);//指向了d1对象
console.log(this.a); //结果为ss
}
f1()
},
}
d1.f()
首先d1.f(),d1对象调用f普通函数,那么里面首先会打印ss,然后f1()函数没有调用者,而且还是一个箭头函数,那么就会从上下文寻找this对象,即上一个调用者,即为d1,所以所以f1()函数里面指向的this就为d1,打印结果就为ss
  • 5.嵌套箭头函数
      var a = 'xx';
var d1 = {
a:'ss',
f:()=>{
console.log(this.a);//xx
var f1=()=>{
console.log(this);//指向了window对象
console.log(this.a); //结果为xx
}
f1()
},
}
d1.f()
首先d1.f()调用的是箭头函数,那么就会往上找,即为window对象,所以调用f会打印xx,然后里面又嵌套了一个箭头函数f1,所以f1也会往上找,f1->d1->window,所以f1中this的指向也是window,打印结果为xx

ajax处理请求失败和请求成功的方式

  • html部分代码
$(".del").on("click", function () {
var delete_id = $(this).prev().text();
var ths = $(this); //因为下面的函数中this指向的不是我们的标签按钮,所以通过一个变量来保存一下这个$(this),方便后面使用
swal({
title: "are you sure?",
text: "要谨慎!",
type: "warning",
showCancelButton: true,
confirmButtonClass: "btn-danger",
confirmButtonText: "确定删除",
cancelButtonText: "容我三思",
closeOnConfirm: false
},
//点击确认删除时触发的函数
function () {
$.ajax({
url:'/ajax_delete_book/'+'100'+'/',//这边暂时写死了100目的是要处理返回请求失败的结果,100对应的其实是要删除的id
type:'get',
success:function(res){
//当状态码为2xx或者3xx时才认为是请求正常成功了,会触发success对应的函数,但是当状态为4xx/5xx的时候,ajax认为此次请求是失败的会触发error属性对应的函数
if (res==='ok'){
console.log('okokok');
//关闭弹框
swal('删除成功!','你可以准备跑路了!','success');
//局部刷新,删除对应记录
ths.parent().parent().remove(); }else{
console.log('出错啦!')
}
};
error:function(res){
if (res.status===404){
swal('删除失败!',res.responseText,'error');
//res.responseText是后台响应回来的错误信息
}
}
}
})
  • views视图代码
      def ajax_delete_book(request,pk):
try:
models.Book.objects.get(pk=pk).delete()
except:
return HttpResponse('找不到对应的资源!!!',status=404)#将响应状态码改为404
return HttpResponse('OK')

CSRF跨站请求

  • cookie执行流程

  • csrf攻击流程

      如何防止csrf攻击呢?我们自己的网站要防止这个事情
csrftoken机制,csrf攻击的最多的方式
django已经做好了这个机制
如下图
  • django中的csrf机制

form表单通过csrftoken认证

  • login.html文件
      <form action='/login/' method='post'>
{% csrf_token %} //会生成一个隐藏的input标签,value属性里面放着token值,name属性值为csrfmiddlewaretoken
用户名:<input type='text' name='username'>
<input type='submit'>
</form>
{% csrf_token %}当我们使用from表单标签来发送请求时,如果需要csrftoken认证,那么必须将它写到我们的form表单标签里面,里面的任意位置。
生成的隐藏标签为:
<input type="hidden" name="csrfmiddlewaretoken" value="WVHKQeAuMS4RGqyLybryIBAfacDa1Dp7PEaB3Badv3y0fvLqydX36xAVen6z3oS4">

校验过程解释

      html页面中的
{% csrf_token %}
<input type="hidden" name="csrfmiddlewaretoken" value="WVHKQeAuMS4RGqyLybryIBAfacDa1Dp7PEaB3Badv3y0fvLqydX36xAVen6z3oS4"> cookie中的
csrftoken:CeFG6SA8Y8hcHAX5R93sxrS37v3iFFlcvX8xjfaRHjLlgFaKRbzXVnSJbGwHHqO9 注意:它们两个的token值是不相同的,这个不用管,到时发送给后台的时候,django会处理的 django会取出提交数据部分的token值和cookie中的token值进行比较:
WVHKQeAuMS4RGqyLybryIBAfacDa1Dp7PEaB3Badv3y0fvLqydX36xAVen6z3oS4 --前32位可以对后面的几位进行解密,html中的token解密出secret_key1 一个字符串 CeFG6SA8Y8hcHAX5R93sxrS37v3iFFlcvX8xjfaRHjLlgFaKRbzXVnSJbGwHHqO9 --前32位可以对后面的几位进行解密,cookie中的token解密出secret_key2 一个字符串
secret_key1 = secret_key2 说明:
token字符串的前32位是salt盐,后面是加密后的token,通过salt能解密出唯一的secret。
django会验证表单中的token和cookie中的token是否能解出同样的secret,secret一样则本次请求合法。 MIDDLEWARE = [
...
'django.middleware.csrf.CsrfViewMiddleware',
...
]
源码
def _compare_salted_tokens(request_csrf_token, csrf_token):
# Assume both arguments are sanitized -- that is, strings of
# length CSRF_TOKEN_LENGTH, all CSRF_ALLOWED_CHARS.
return constant_time_compare(
_unsalt_cipher_token(request_csrf_token),
_unsalt_cipher_token(csrf_token),
) def _unsalt_cipher_token(token):
"""
Given a token (assumed to be a string of CSRF_ALLOWED_CHARS, of length
CSRF_TOKEN_LENGTH, and that its first half is a salt), use it to decrypt
the second half to produce the original secret.
"""
salt = token[:CSRF_SECRET_LENGTH]
token = token[CSRF_SECRET_LENGTH:]
chars = CSRF_ALLOWED_CHARS
pairs = zip((chars.index(x) for x in token), (chars.index(x) for x in salt))
secret = ''.join(chars[x - y] for x, y in pairs) # Note negative values are ok
return secret

ajax请求通过csrftoken认证三种方式

  • 方式1
      首先在html文件中间,写上{% csrf_token %}
{% csrf_token %}
用户名: <input type="text" id="uname" >
<button id="btn">ajax提交</button> jquey代码
$('#btn').click(function(){
var uname = $('#uname').val();
//获取csrfmiddlewaretoken的input标签value属性对应的值
var token = $('[name="csrfmiddlewaretoken"]').val(); $.ajax({
url:'/login/',
type:'post',
//将token值放到请求数据部分,token的键必须是csrfmiddlewaretoken
data:{uname:uname,csrfmiddlewaretoken:token},
success:function(res){
console.log(res);
}
})
})
  • 方式2
      使用'{{ csrf_token }}'这个模板渲染标签,这样就不要我们在html页面中写{% csrf_token %}了。
$('#btn').click(function(){
var uname = $('#uname').val();
//直接就能得到csrfmiddlewaretoken的input标签value属性的值
var token= '{{ csrf_token }}'; $.ajax({
url:'/login/',
type:'post',
data:{uname:uname,csrfmiddlewaretoken:token},
success:function(res){
console.log(res);
}
})
})
  • 方式3
      借助js操作cookie的方法来获取到cookie中的csrftoken那个键对应的值
然后将这个值组成一个请求头,放到此次请求中
headers:{'X-CSRFToken':这个值}
这个值,通过js能够获取到,通过jquery也能获取到,我们看一下jquery如何操作cookie 操作步骤,下载与引入
jquery.cookie.js基于jquery;先引入jquery,再引入:jquery.cookie.js;下载:http://plugins.jquery.com/cookie/
<script src="{% static 'jquery.js' %}"></script> #这个要在上面
<script src="{% static 'jquery.cookie.js' %}"></script> {% csrf_token %} //需要在html中写上{% csrf_token %}或{{ csrf_token }},不然此次获取这个html页面的时候,响应中不会有这个csrftoken的cookie的值
$('#btn').click(function(){
var uname = $('#uname').val();
//通过js获取jquery来获取cookie中的csrftoken这个键对应的token值
var token = $.cookie('csrftoken');
$.ajax({
url:'/login/',
type:'post',
//将获取到的token值放到请求头中,这个请求头键值对的键必须是'X-CSRFToken'
headers:{
'X-CSRFToken':token,
},
//django先去获取请求数据部分的token值,获取不到,就去找一个叫做X-CSRFToken请求头键值对,它的值和cookie中的csrftoken的值要相等。
data:{uname:uname,},
success:function(res){
console.log(res);
}
})
})

ajax上传文件

  • html文件
      用户名:<input type='text' name='username'>
密码:<input type='text' name='password'>
头像:<input type='file' name='touxiang'>
<button id='sub'>上传</button> js部分
$('$sub').click(function(){
//ajax上传文件必须依赖于FormData对象
var formdata = new FormData(); var uname = $('[name="username"]').val();
var pwd = $('[name="password"]').val();
//获取浏览器上的文件数据方法:$('[name="touxiang"]')[0].files[0]
var file_obj = $('[name="touxiang"]')[0].files[0]; formdata.append('uname',uname)//后面取数据也是用request.POST.get('uname')
formdata.append('pwd',pwd)
formdata.append('csrfmiddlewaretoken','{{ csrf_token }}') //request.FILES
formdata.append('touxiang',file_obj) $.ajax({
url:'',//如果路径为空,那么使用当前页面的路径,也就是往当前路径下进行提交
type:'post',
data:formdata,
//下面的两个参数的意思是,不要对数据进行任何的预处理和加工
processData:false,
contentType:false, success:function(res){
console.log(res);
}
})
})
  • views文件
      def upload(request):
if request.method == 'GET':
return render(request,'upload.html')
else:
print(request.POST)
print(request.FILES)
file_obj = request.FILES.get('touxiang')
with open(file_obj.name,'wb') as f:
for i in file_obj:
f.write(i)
//第二种写法
//默认一次返回大小为65536B,也就是64KB,最大2.5M
for chunk in file_obj.chunks():
f.write(chunk)
return HttpResponse('ok')

上传多文件 自行拓展 后续补充

  • html文件
      <input type='file' name='touxiang' multiple> //multiple为上传多个

django学习第十二天--ajax请求和csrftoken认证的三种方式的更多相关文章

  1. ios网络学习------4 UIWebView的加载本地数据的三种方式

    ios网络学习------4 UIWebView的加载本地数据的三种方式 分类: IOS2014-06-27 12:56 959人阅读 评论(0) 收藏 举报 UIWebView是IOS内置的浏览器, ...

  2. Struts2学习(二)运行Action中方法的三种方式

    1.运行execute()方法 一般的能够直接在action中书写execute,调用action时会自己主动运行此方法 2.配置method方法 在struts.xml中配置action时.写met ...

  3. Django框架之ORM的相关操作之多对多三种方式(五)

    在之前的博客中已经讲述了使用ORM的多对多关系表,现在进行总结一下: 1.ORM自动帮助我们创建第三张表 2.手动创建第三张表,第三张表使用ForeignKey指向其他的两张表关联起来 3.手动创建第 ...

  4. python 全栈开发,Day94(Promise,箭头函数,Django REST framework,生成json数据三种方式,serializers,Postman使用,外部python脚本调用django)

    昨日内容回顾 1. 内容回顾 1. VueX VueX分三部分 1. state 2. mutations 3. actions 存放数据 修改数据的唯一方式 异步操作 修改state中数据的步骤: ...

  5. ajax的data传参的两种方式

    ajax的data传参的两种方式 本文为转载. 1.[javascript] view plain copy /** * 订单取消 * @return {Boolean} 处理是否成功 */ func ...

  6. Django文件上传三种方式以及简单预览功能

    主要内容: 一.文件长传的三种方式 二.简单预览功能实现 一.form表单上传 1.页面代码 <!DOCTYPE html> <html lang="en"> ...

  7. 【转】Spring学习---Bean配置的三种方式(XML、注解、Java类)介绍与对比

    [原文]https://www.toutiao.com/i6594205115605844493/ Spring学习Bean配置的三种方式(XML.注解.Java类)介绍与对比 本文将详细介绍Spri ...

  8. Ajax上传数据和上传文件(三种方式)

    Ajax向后端发送数据可以有三种方式:原生Ajax方式,jQuery Ajax方式,iframe+form 方式(伪造Ajax方式) <!DOCTYPE html> <html la ...

  9. 【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】

    不考虑第三方框架,如果只使用JDK提供的API,那么可以使用三种方式调用WebService服务:另外还可以使用Ajax调用WebService服务. 预备工作:开启WebService服务,使用jd ...

  10. PHP的学习--连接MySQL的三种方式

    记录一下PHP连接MySQL的三种方式. 先mock一下数据,可以执行一下sql. /*创建数据库*/ CREATE DATABASE IF NOT EXISTS `test`; /*选择数据库*/ ...

随机推荐

  1. [转帖]使用Transformers推理

    https://github.com/ymcui/Chinese-LLaMA-Alpaca/wiki/%E4%BD%BF%E7%94%A8Transformers%E6%8E%A8%E7%90%86 ...

  2. 关于JVM指针压缩性能的研究

    关于JVM指针压缩性能的研究 摘要 JVM的内存对消最小是 8bytes 所以32G内存的情况下可以使用 32位的指针就可以了. 32位就是4G 在乘以最小的内存extent 8 bytes 的出来可 ...

  3. OpenSSH 9.2P1升级以及版本显示的处理过程

    说明 本次维护的时间是 2023-2-9 最新已发布的补丁是 OpenSSH9.2P1版本 其他本本应该是类似处理. 下载介质 在 OpenSSH官网打开相关界面. http://www.openss ...

  4. 【字符串,哈希】【Yandex】Yandex7736

    2023.6.30 Problem Link 定义一个串 \(S\) 是好的,当且仅当 \(S\) 可以不断消去相邻两个相同字符直至消空.给定一个长为 \(n\) 的字符串 \(s\),求有多少个有序 ...

  5. Vue中is属性的用法 可以动态切换组件

    is 是组件的一个属性,用来展示组件的名称 is和component联用哈 vue提供了component来展示对应的组件名称 compont是一个占位符,is这个属性,用来展示对应的组件名称 三个子 ...

  6. docker 发布web项目到linux

    一.准备工作 1.连接到Liunx的工具 MobaXterm 填好Ip 直接点ok就行 输入用户名和密码进入系统 2.已发布的.netcore网站或微服务 在要发布的项目上右键---->添加-- ...

  7. python3 ACM模式的输入输出例子教学

    Python的输入是字符串,所以要自己转类型 strip去掉左右两端的空白符,返回str slipt把字符串按空白符拆开,返回[str] map把list里面的值映射到指定类型,返回[type] EO ...

  8. Prompt工程师指南[高阶篇]:对抗性Prompting、主动prompt、ReAct、GraphPrompts、Multimodal CoT Prompting等

    Prompt工程师指南[高阶篇]:对抗性Prompting.主动prompt.ReAct.GraphPrompts.Multimodal CoT Prompting等 1.对抗性 Prompting ...

  9. ARKit的理解与使用

    AR概述 AR的意义:让虚拟世界套与现实世界建立联系,并可以进行互动. AR的技术实现:通过实时地计算摄影机输出影像的位置及角度,并在内部通过算法识别将场景中的事物,然后在内部模拟的三维坐标系中给识别 ...

  10. vscode连不上云服务器,一直报超时错误|但是xshell那些又可以连上?为什么vscode连不上?|命令行输出管道报错 -bash: command not found 导致的一系列问题

    前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量博客汇总https://blog.cs ...