一 Ajax简介
翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。AJAX 不是新的编程语言,而是一种使用现有标准的新方法.
特点:
1.异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
2.浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
2.示例
login.html里面内容
{% load static %} <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <!-- 告诉浏览器安装IE的最高版本渲染浏览器--> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- 整个网站和等比缩放,目的兼容:移动端,web端。可以完整访问网站--> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>标题</title> <!-- Bootstrap 引入文件 --> <link href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}" rel="stylesheet"> </head> <body> <h1>你好,欢迎来到登录页面</h1> <form action="/login/" method="post"> {% csrf_token %} 用户名 <input type="text" id="username" name="username"> 密码 <input type="password" id="pwd" name="password"> {# <input type="submit" id="btn">#} {# <button>提交</button>#} <input type="button" id="btn" value="确认">
<span id="error" style="color:red;font-size:12px"><span>
</form> {#<button id="btn">提交</button>#} <script src="{% static 'jquery-3.5.1.js' %}"></script> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> <script> $("#btn").click(function () { $.ajax({ url:'/login/',//方式1:直接获取请求地址不要忘了加双引号或者单引号 {#url:'{% url "login" %}',//方式2:通过url以及别名获取地址#} type:'post', data:{ uname:$('#username').val(), pwd:$('#pwd').val(), csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(), //方式1:直接获取。因为我们表单中使用csrf_token,这个html文档中就是一个p标签,name属性等于csrfmiddlewaretoken,他的value值就是crstoken,因此我们可以通过js获取值 {#csrfmiddlewaretoken:'{% csrf_token %}',}//方式2:通过url以及别名获取地址#} }, //res就是返回的响应数据 success:function (res) { var retStr = JSON.parse(res);//json序列化 if (retStr['code']===302){ $("#error").text(retStr['msg']); }else if(retStr['code']===0){ location.href = retStr['login_url'] } console.log(retStr,typeof retStr) } }) }) </script> </body> </html>
views.py里面的内容
from django.shortcuts import render,HttpResponse,redirect from django.views import View # Create your views here. import json class LoginView(View): def get(self,request): return render(request,'login.html') def post(self,request): # name = request.POST.get('username') # pwd = request.POST.get('pwd') #ajax data里面的键来获取数据 name = request.POST.get('uname')//必须使用ajax传的data里面参数名称来获取 pwd = request.POST.get('pwd') if name=='zxb' and pwd =='123': # return render(request,'index.html') ret = {'code':0,'login_url':'/index/'} return HttpResponse(json.dumps(ret)) else: # ret = {'code':302,'redirect_url':'/login/'} ret = {'code':302,'msg':'用户名或者密码错误!!!'} return HttpResponse(json.dumps(ret)) def index(request): return render(request,'index.html')
urls.py里面的内容
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.LoginView.as_view(),name='login'), url(r'^index/', views.index,name='index'), ]
注意:如果我们的ajax的js代码写在js文件中,我们html通过引入来执行js代码,我们就不可以使用 url:'{% url "login" %},csrfmiddlewaretoken:'{% csrf_token %}',这种形式因为我们js文件中不认识这些,这些只是在html文件中才可以使用,如果要在js中使用我们就要用方式1。如下就是js文件中代码
$("#btn").click(function () { $.ajax({ url:'/login/', //url:'{% url "login" %}', type:'post', data:{ uname:$('#username').val(), pwd:$('#pwd').val(), csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(), //csrfmiddlewaretoken:'{% csrf_token %}', }, //res就是返回的响应数据 success:function (res) { var retStr = JSON.parse(res) if (retStr['code']===302){ var spanEle = document.createElement('span'); $(spanEle).text(retStr['msg']); $('form').append(spanEle); }else if(retStr['code']===0){ location.href = retStr['login_url'] } console.log(retStr,typeof retStr) } }) })
4.AJAX的优缺点
优点:
1.AJAX使用JavaScript技术向服务器发送异步请求;
2.AJAX请求无须刷新整个页面;
3.因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能
二Ajax发送各种请求方法以及视图函数解析传过来的数据
1.Ajax不指定请求方式的情况下默认
四 Ajax文件上传
请求头ContentType
ContentType指的是请求体的编码类型,常见的类型共有3种
1 application/x-www-form-urlencoded
这应该是最常见的 POST 提交数据的方式了。浏览器的原生 <form> 表单,如果不设置 contentType
属性,那么最终就会以 默认格式application/x-www-form-urlencoded 方式提交数据,ajax默认也是这个。请求类似于下面这样(无关的请求头在本文中都省略掉了):
视图函数解析传递的数据直接使用JsonResponse(ret)来传递数据。使用request.Post,request.Get来获取数据,因为django内置的已经给我们解析了,直接获取。
2 multipart/form-data(用于上传文件使用)
这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 contentType
等于 multipart/form-data,form表单不支持发json类型的contenttype格式的数据,而ajax什么格式都可以发,也是ajax应用广泛的一个原因。直接来看一个请求示例:(了解)
1.普通form表单上传文件
html代码:form表单上传文件必须要写enctype="multipart/form-data",不然无法上传文件。
<form action="{% url 'upload' %}" method="post" enctype="multipart/form-data"> 头像:<input type="file" name="head_pic"> 用户名:<input type="text" name="userName"> <input type="submit"> </form>
2.ajax上传文件
html代码:
1.不需要要form标签,因为ajax提交数据,与form提交数据无关。
2.首先要创建var formdata = new FormData();对象就,将需要传的参数使用append方法传入。
3. 必须要写contentType:false,processData:false,不写会报错。
ajax上传文件:<input type="file" id="file"> ajax用户名:<input type="text" id="uname"> <button id="btn">提交</button> <script src="{% static 'jquery-3.5.1.js' %}"></script> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> <script> $("#btn").click(function () { var formdata = new FormData(); formdata.append('username',$("#uname").val()); formdata.append('head_pic',$("#file")[0].files[0]) formdata.append('csrfmiddlewaretoken',$('[name=csrfmiddlewaretoken]').val()) $.ajax({ url:"{% url 'upload' %}", type:"post", data:formdata, //下面两个必须写,不写就报错 contentType:false, //不设置内容类型 processData:false, //不设置数据 success:function (res) { console.log(res); } }) }) </script>
传递file参数如下图:
url代码
url(r'^upload/', views.upload,name='upload'),
视图函数获取前端数据
1.使用request.FILES获取一个传过来的对象,通过get方法根据key获取对应的值。注意get("file名称")获取的是上传的文件的文件句柄,因此我们可以循环写入获取文件。
import os def upload(request): if request.method=='GET': return render(request,'uploadFile.html') else: print(request.POST) #<QueryDict: {'head-pic': ['p01.png'], 'userName': ['zxb']}> print(request.FILES) #<MultiValueDict: {'head-pic': [<InMemoryUploadedFile: p01.png (image/png)>]}> 内存中的文件对象 #读取文件保存到本地 file_obj = request.FILES.get('head_pic') #返回一个文件对象(文件句柄) print(file_obj) #p01.png 为什么对象打印出来文件名字,因为里面有——str--方法 print(file_obj.name) #p01.png file_name = file_obj.name file_path = os.path.join(BASE_DIR,'statics','picture',file_name) print(file_path) #写文件方式1 # with open(file_path,'wb') as f: #每次读取的data不是固定长度的,和读取其他文件一样,每次读一行,识别符为 ,遇到这几个符号就算是读了一行 # for i in file_obj: # f.write(i) #写文件方式2: with open(file_path,'wb') as f: for chunks in file_obj.chunks(): ##chunks()默认一次返回大小为经测试为65536B,也就是64KB,最大为2.5M,是一个生成器 f.write(chunks) return HttpResponse("ok")
3. contentType:"application/json"
json格式请求数据传递到视图函数数据格式为json
$.ajax({ url:"{% url 'data' %}", type:'post', data:JSON.stringify({k1:'v1',k2:'v2'}), contentType:"application/json", success:function (res) { console.log(res) /*for(var i in res){ }*/ $.each(res,function (k,v) { console.log(k,v) //k(索引),v(数值) var liStr='<li>'+v.toString()+'</li>' //toString数字转字符串方法 $("ul").append(liStr) }) } })
视图函数需要解析ajax传过来的参数,因为视图函数接收到数据格式为byte类型,需要转换,并且需要反序列化,才可以正常的取值操作。
def data(request): li=[11,22,33] print(request.POST) #<QueryDict: {}> print(request.body) #b'{"k1":"v1","k2":"v2"}' para =request.body.decode('utf-8') print(para,type(para)) #{"k1":"v1","k2":"v2"} <class 'str'> para = json.loads(para) print(para,type(para)) #{'k1': 'v1', 'k2': 'v2'} <class 'dict'> return JsonResponse(li,safe=False)
五 关于json
1.js的stringify与parse方法
JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象
JSON.parse('{"name":"chao"}');
JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。
JSON.stringify({"name":"zxb"})
2.通过json学列化时间日期格式数据的时候需要注意,不能直接序列化,使用下面的类就可以进行序列化
import json from datetime import datetime from datetime import date #对含有日期格式数据的json数据进行转换 class JsonCustomEncoder(json.JSONEncoder): def default(self, field): if isinstance(field,datetime): return field.strftime('%Y-%m-%d %H:%M:%S') elif isinstance(field,date): return field.strftime('%Y-%m-%d') else: return json.JSONEncoder.default(self,field) d1 = datetime.now() dd = json.dumps(d1,cls=JsonCustomEncoder) print(dd)
三 Ajax请求设置csrf_token
方式1
通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送。
$.ajax({ url: "/cookie_ajax/", type: "POST", data: { "username": "chao", "password": 123456, "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val() // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中 }, success: function (data) { console.log(data); } })
方式2
$.ajaxSetup({ data: {csrfmiddlewaretoken: '{{ csrf_token }}' }, });
方式3(后面再说)
通过获取返回的cookie中的字符串 放置在请求头中发送。
注意:需要引入一个jquery.cookie.js插件。
<script src="{% static 'jquery.cookie.js' %}"></script> $("#btn").click(function () { $.ajax({ url: "{% url 'test' %}", type: 'post', {#方式2:ajax自己发送cookie#} headers:{ "X-CSRFToken":$.cookie('csrftoken') }, data:{ usename:$("#usename").val(), {##方式1:#} {#csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val()#} }, success:function (response) { console.log(response) } }) })
jquery.cookie.js插件获取步骤:
1.下载与引入:jquery.cookie.js基于jquery;先引入jquery,再引入:jquery.cookie.js;下载:http://plugins.jquery.com/cookie/
2.解压下载包,找到下面文件,放到项目中
jquery操作cookie方法:https://www.cnblogs.com/zhuxibo/p/14702067.html