Django框架09 /ajax、crsf、settings导入
目录
1. ajax概述
- 使用Javascript语言与服务器进行异步交互,AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
- 在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
- 特性:异步请求/ 局部刷新
2. ajax应用
-
代码示例:
login.html
{% load static %} <!-- 引入jquery文件的第二种方式 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!-- form方式提交数据 --> <form action="" method="post"> {% csrf_token %} 用户名: <input type="text" name="username"> 密码: <input type="password" name="password"> <input type="submit"> </form> <!-- ajax方式提交数据 --> {% csrf_token %} 用户名: <input type="text" id="username"> 密码: <input type="password" id="password"> <button id="sub">提交</button> <span class="error"></span> </body> <!-- 原jquery文件引入方式 --> <script src="/static/js/jquery.js"></script> <!-- 引入jquery文件的第二种方式 --> <script src="{% static 'js/jquery.js' %}"></script> <!-- 引入jquery.cookie文件,通过jquer操作cookie --> <script src="{% static 'js/jquery.cookie.js' %}"></script> <script> $('#sub').click(function () { var uname = $('#username').val(); var pwd = $('#password').val(); var csrf = '{{ csrf_token }}'; //不发送数据 $.ajax({ url:'{% url "login" %}', type:'get', success:function (res) { console.log(res); } }) //发送数据 $.ajax({ url: '{% url "login" %}', type: 'post', data: {username: uname, password: pwd}, success: function (res) { console.log(res); if (res === '1') { // $('.error').text('登录成功'); location.href = '/home/'; // http://127.0.0.1:8000/home/ } else { $('.error').text('用户名密码错误!'); } } }) }) </script> </html>
view.py
def login(request): if request.method == 'GET': return render(request,'login.html') else: uname = request.POST.get('username') # ajax中data设置的键 pwd = request.POST.get('password') if uname == 'liu' and pwd == '123': return HttpResponse('1') else: return HttpResponse('0') def home(request): return render(request,'home.html')
3. ajax上传文件
-
代码示例:
upload.html
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>文件上传</h1> <!-- form表单上传 enctype="multipart/form-data" *** --> <form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} 用户名: <input type="text" name="username"> 密码: <input type="password" name="password"> 头像: <input type="file" name="file"> <input type="submit"> </form> <!-- ajax上传 --> {% csrf_token %} 用户名: <input type="text" id="username"> 密码: <input type="password" id="password"> <!-- 上传多个文件 --> 上传文件: <input type="file" multiple> <!-- 上传单个文件 --> 上传文件: <input type="file"> <button id="sub">提交</button> <span class="error"></span> </body> <script src="{% static 'js/jquery.js' %}"></script> <script src="{% static 'js/jquery.cookie.js' %}"></script> <script> $('#sub').click(function () { var formdata = new FormData(); var uname = $('#username').val(); var pwd = $('#password').val(); var file_obj = $('[type=file]')[0].files[0]; formdata.append('username', uname); formdata.append('password', pwd); formdata.append('file', file_obj); $.ajax({ url: '{% url "upload" %}', type: 'post', data: formdata, //必须写/告诉ajax不对data数据进行任何的加工处理 processData: false, //不处理数据 contentType: false, //不设置内容类型 headers: { "X-CSRFToken": $.cookie('csrftoken'), }, success: function (res) { console.log(res); if (res === '1') { $('.error').text('上传成功'); } else { $('.error').text('上传错误!'); } } }) }) </script> </html>
view.py
def upload(request): if request.method == 'GET': return render(request,'upload.html') else: print(request.POST) print(request.FILES) uname = request.POST.get('username') pwd = request.POST.get('password') file_obj = request.FILES.get('file') # 文件对象---相当于是文档句柄 print(file_obj.name) # 文件名 with open(file_obj.name,'wb') as f: # 按行将文件写入 for i in file_obj: f.write(i) # 按固定字节将文件写入,一次65531个字节 for chunk in file_obj.chunks(): f.write(chunk) return HttpResponse('ok')
4. jsonresponse应用
-
代码示例:
jsontest.html
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 用户名: <input type="text" id="username"> 密码: <input type="password" id="password"> <button id="sub">提交</button> <span class="error"></span> </body> <script src="{% static 'js/jquery.js' %}"></script> <script src="{% static 'js/jquery.cookie.js' %}"></script> <script> $('#sub').click(function () { var uname = $('#username').val(); var pwd = $('#password').val(); $.ajax({ url: '{% url "jsontest" %}', type: 'post', data: {username: uname, password: pwd}, headers: { "X-CSRFToken": $.cookie('csrftoken'), // contentType:'application/json', // 可以指定传输文件的类型,指定json后django无法解析 }, success: function (res) { //方式一: var res = JSON.parse(res); //-- 相当于python中json.loads() console.log(res, typeof res); //将对象转换成字符串类型 //JSON.stringify() -- 相当于python中json.dumps //方式二、三 if (res.status === 1000) { location.href = '/home/'; // http://127.0.0.1:8000/home/ } else { $('.error').text(res.msg); } } }) }) </script> </html>
view.py
def jsontest(request): """ 状态码; 1000 : 登录成功 1001 : 登录失败 :param request: :return: """ if request.method == 'GET': return render(request,'jsontest.html') else: username = request.POST.get('username') pwd = request.POST.get('password') ret_data = {'status':None,'msg':None} print('>>>>>',request.POST) # 如果ajax传输指定的内容类型是json的话,django无法解析 # <QueryDict: {'{"username":"123","password":"123"}': ['']}> if username == 'liu' and pwd == '123': ret_data['status'] = 1000 # 状态码 ret_data['msg'] = '登录成功' else: ret_data['status'] = 1001 # 状态码 ret_data['msg'] = '登录失败' # 方式一: ret_data_json = json.dumps(ret_data,ensure_ascii=False) return HttpResponse(ret_data_json) # 方式二: return HttpResponse(ret_data_json,content_type='application/json') # 方式三:/省略将字典转换成字符串和指定类型 return JsonResponse(ret_data) # 注意:当传输的数据ret_data是非字典数据类型的话JsonResponse不会序列化 return JsonResponse(ret_data,safe=False) # django没有json类型解释器 # django对内容类型解析伪代码 ''' ret = username=123&password=123 -- content-type:...urlencoded if content-type == 'urlencoded': res_list = ret.split('&') for i in res_list: k = i.split('=') request.POST[k[0]] = k[1] elif content-type=='multipart/form-data': ... request.FILES elif content-type == 'application/json' '''
-
注意:
外部文件导入的方式来写js代码,那么js代码中不能写django的模板语法,因为html文件的加载顺序:url--视图--html模板渲染 --- return给浏览器 -- 浏览器渲染 --- srcipt的src --才去请求js文件 --那么这个js文件的代码此时才加载到你的html文件中 -- 就没有模板渲染的步骤了 -- 就没有办法替换对应的模板语法.
5. csrftoken /跨站请求伪造
-
csrf简述
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。攻击者通过HTTP请求将数据传送到服务器,从而盗取回话的cookie。盗取回话cookie之后,攻击者不仅可以获取用户的信息,还可以修改该cookie关联的账户信息。
-
解决csrf攻击
解决csrf攻击的最直接的办法就是生成一个随机的csrftoken值,保存在用户的页面上,每次请求都带着这个值过来完成校验。
-
form表单过csrf认证
<form action="" method="post"> {% csrf_token %} <!-- form表单里面加上这个标签,模板渲染之后就是一个input标签 --> type=hidden name=csrfmiddlewaretoken value='asdfasdfasdf' 用户名: <input type="text" name="username"> 密码: <input type="password" name="password"> <input type="submit"> </form>
-
ajax过csrf认证
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% csrf_token %} 用户名: <input type="text" id="username"> 密码: <input type="password" id="password"> <button id="sub">提交</button> <span class="error"></span> </body> <script src="{% static 'js/jquery.js' %}"></script> //引入jquery.cookie.js文件通过jqery操作cookie <script src="{% static 'js/jquery.cookie.js' %}"></script> <script> $('#sub').click(function () { var uname = $('#username').val(); var pwd = $('#password').val(); //方式一: var csrf = $('[name=csrfmiddlewaretoken]').val(); //方式二: var csrf = '{{ csrf_token }}'; $.ajax({ url: '{% url "login" %}', type: 'post', //方式一、二: data:{username:uname,password:pwd,csrfmiddlewaretoken:csrf}, //方式三: data: {username: uname, password: pwd}, headers: { "X-CSRFToken": $.cookie('csrftoken'), }, //其实在ajax里面还有一个参数是headers,自定制请求头,可以将csrf_token加在这里,我们发contenttype类型数据的时候,csrf_token就可以这样加 success: function (res) { console.log(res); if (res === '1') { location.href = '/home/'; } else { $('.error').text('用户名密码错误!'); } } }) }) </script> </html>
6. django中setting引用
-
方式一:
from 项目名 import settings # 只能从项目目录下的setting去查找,找不到会报错,没有此setting项目也能启动
-
方式二:
from django.conf import settings #推荐使用 # 先从本项目目录下的setting查找,找不到去global setting去查找 print(settings.BASE_DIR) #/static/