一 Ajax简介
1 Ajax的介绍
AJAX翻译成中文就是"异步Javascript和XML"。即使用JavaScript语言与服务器进行异步交互,传输的数据为XML(当然,传输数据不只是XML,现在更多使用json数据)
同步交互:客户端发出一个请求后,需要等待服务器结束后才能发出第二个请求
异步交互:客户端发出一个请求后无需等待服务器响应结束,就可以发出第二个请求
AJAX除了异步的特定外还有一个就是:浏览器局部刷新,(这一特点就给用户的感受是在不知不觉完成请求和响应过程)
2 Ajax的应用场景
当我们在百度中输入一个“老”字后,会马上出现一个下拉列表!列表中显示的是包含“老”字的4个关键字。
其实这里就使用了AJAX技术!当文件框发生了输入变化时,浏览器会使用AJAX技术向服务器发送一个请求,查询包含“老”字的前10个关键字,然后服务器会把查询到的结果响应给浏览器,最后浏览器把这4个关键字显示在下拉列表中。
- 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
- 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询名为zhangSan的用户是否存在,最终服务器返回true表示名为lemontree7777777的用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”。
- 整个过程中页面没有刷新,只是局部刷新了;
- 在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;
3、ajax的优点
优点:
- AJAX使用Javascript技术向服务器发送异步请求;
- AJAX无须刷新整个页面;
- 因为服务器响应内容不再是整个页面,而是页面中的局部,所以AJAX性能高;
二 基于jquery的Ajax实现
<script type="text/javascript"> $(function () { $(".Ajax").click(function () { // 发送Ajax请求 $.ajax({ url:"/test_ajax/", // 请求URL type:"get", // 请求方式post success:function (data) { // 回调函数 console.log(data); $("#aj").html(data) } } ) }) }) </script>
三 基于Ajax的登录验证
在注册表单中,当用户填写了用户名之后,把光标移开后,会自动向服务器发送异步请求。服务器返回True或False,返回True表示这个用户名以及注册过,返回false表示没有注册过。客户端得到服务器返回结果后,确定是否在用户名文本框显示"用户名已被注册"的错误信息
Ajax代码:
$.ajax({ url:"/login/", type:"POST", data:{ username:$('#username').val(), password:$('#password').val() }, success:function (data) { console.log(data); var ret = JSON.parse(data); if (ret.state){ location.href = 'http://www.baidu.com' }else { $('.error').html(ret.msg).css({'color':'red'}) } })
视图函数代码:
def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') ret = Users.objects.filter(username=username,password=password) message = { 'state':False, 'msg':None } if ret: message['state'] = True else: message['msg'] = '用户名或密码错误' message = json.dumps(message) return HttpResponse(message) return render(request,'index.html')
四 js接收Python的json对象
在json的编码过程中,会存在从Python原始类型向json类型的转换过程,具体的转换如下
python ----> json
ajax发送JSON数据
$(".btn").click(function(){ $.ajax({ url:"", type:"post", contentType:"application/json" data:JSON.stringfy({ a:1, b:2 }), success:function(data){ console.log(data) } }) def get_json(request): if request.method == 'POST': print(request.body) # 请求报文
五 Jsonp跨域请求
浏览器有一个很重要的概念--同源策略。 所谓同源是指,域名协议,端口相同。不同源的客户脚本在没有明确授权的情况下不能读写对方资源。
1 JSONP的js实现
JSONP是JSONwith Padding的缩略。可以让网页从别的域名获取资料,即跨域读取数据
它是一个非官方的协议,它允许服务器端集成Script tags返回客户端, 通过JavaScript callback的形式实现跨域访问
示例一:
<input type="button" onclick="jonpRequest()" value="跨域请求"> <script> tag = null; function jonpRequest(){ var tag = document.createElement('script'); tag.src = "http://baidu.com/"; document.head.appendchild(tag); } function list(arg){ console.log(arg); document.head.removeChild(tag); } </script>
示例二:
<script> function test1(w){ alert(w) } </script> <script> tag = null; function jonpRequest(){ var tag = document.createElement('script'); tag.setAttribute("type", "text/javascript") tag.src = "http://127.0.1/jquery_get"; document.head.appendchild(tag); } function list(arg){ console.log(arg); document.head.removeChild(tag); } </script> def jquery_get(req): print("hello") return HttpResponse("test1('kkk')")
2 Jquery实现跨域请求
示例一:
<script type="text/javascript"> $.ajax({ url:"http://127.0.0.1:8002/get_byjsonp", dataType:"jsonp", jsonp:'callbacks', jsonpCallback:"fetch" });
function fetch(arg){ alert(arg); } #------------------------------- http://127.0..1:8002/get_byjsonp def get_byjsonp(req): callback = req.GET.get('callbacks') print(callback) return HttpResponse('%s("harry")' %callback)
示例二:
<script type="text/javascript"> $.ajax({ url:"http://127.0.0.1:8002/get_byjsonp", dataType:"jsonp", jsonp:'callbacks', success:function(data){ alert(data) } }); #------------------------------- http://127.0..1:8002/get_byjsonp def get_byjsonp(req): callback = req.GET.get('callbacks') print(callback) # jQuery23232415124215_231243 return HttpResponse('%s("harry")' %callback)
六ajax使用seralize
如果我们想使用ajax向后端提交数据,但是一个form表单下有多个input标签或select标签,如果我们想一下全部获取可以使用seralize
serialize()
函数用于序列化一组表单元素,将表单内容编码为用于提交的字符串。
serialize()
函数常用于将表单内容序列化,以便用于AJAX提交。
该函数主要根据用于提交的有效表单控件的name和value,将它们拼接为一个可直接用于表单提交的文本字符串,该字符串已经过标准的URL编码处理(字符集编码为UTF-8)。
该函数不会序列化不需要提交的表单控件,这和常规的表单提交行为是一致的。例如:不在<form>标签内的表单控件不会被提交、没有name属性的表单控件不会被提交、带有disabled属性的表单控件不会被提交、没有被选中的表单控件不会被提交。
<form id='f1'> <input type='text' name='input1' /> <input type='text' name='input2' /> <input type='text' name='input3' /> <input type='text' name='input4' /> <input type='text' name='input5' /> <input type='text' name='input6' /> <select mulitiple> <option></option> </select> </form> $.ajax({ url: data:$("#f1").seralize(), traditional:true, })
对<form>元素进行序列化可以直接序列化其内部的所有表单元素。
// 序列化<form>内的所有表单元素 // 序列化后的结果:uid=1&username=%E5%BC%A0%E4%B8%89&password=123456&grade=3&sex=1&hobby=1&hobby=2 alert( $("form").serialize() );
我们也可以直接对部分表单元素进行序列化。
// 序列化所有的text、select、checkbox表单元素 // 序列化后的结果:username=%E5%BC%A0%E4%B8%89&password=123456&grade=3&hobby=1&hobby=2 alert( $(":text, select, :checkbox").serialize() );
七 文件上传
1 基于form表单的文件上传
文件和其他的数据类型不一样,是一个二进制的形式
Form上传文件的时候切记要加上:enctype="multipart/form-data"
(1) HTML代码 <form action="/upload/" method="post" enctype="multipart/form-data"> 用户名 <input type="text" name="user"> 头像 <input type="file" name="avatar"> <input type="submit" > </form> (2) 视图函数 def upload(req): if req.method == 'POST': print(req.POST) print(req.FILES) file_obj = req.FILES.get("avatar") # 拿到文件对象的方法 with open("static/%s" % file_obj.name, 'wb') as f: # 拿到文件名字 for line in file_obj: f.write(line) return HttpResponse('OK')
2 基于Ajax的文件上传
FormData
.利用FormData对象
,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()
方法来异步的提交这个"表单".比起普通的ajax,使用FormData
的最大优点就是我们可以异步上传一个二进制文件.$("#upload") 拿到的是一个集合 $("#upload")[0] 就是一个dom对象 $("#upload")[0].files 拿到的是一个filelist $("#upload")[0].files[0] 拿到的是当前最近的文件对象
要是使用FormData一定要加上:
一定要加上:
- contentType:false
- processDate:false #不做预处理
上传示例:
$("#btn").click(function () { var formadata = new FormData(); formadata.append('user',$('#user').val()); formadata.append('avatar',$('#avatar')[0].files[0]); // 取到上传文件的对象 $.ajax({ url:/upload/, type:"post", contentType:false, processData:false, data:formadata, success:function (data) { console.log(data); console.log(123) } }) })
3 补充一个实现上传图片预览功能
上传头像: 点击头像等于点击input <div class="form-group"> <label for="avatar"> 头像 <img id="avatar_img" width="60" height="60" src="/static/blog/img/default.png"> </label> <input type="file" id="avatar"> </div> 实现头像预览功能: <script> $("#avatar").change(function(){ // 获取文件对象 var file_obj = $(this)[0].files[0]; // 获取文件对象的路径 var reader = new FileReader() reader.readAsDataURL(file_obj) // 修改img的src属性 reader.onload = function(){ $("#avatar_img").attr("src", reader.result) }; </script>