python之路(23)ajax进阶及jsonp
目录
- Ajax发送请求
- Ajax上传文件
- jQuery + formData
- 原生XMLHttpRequest + formData
- "伪"Ajax(iframe标签+form)
- 跨域Ajax,JSONP
原生XMLHttpRequest
使用普通的Aax发送请求需要引入JQuery,可能在一些业务上(性能上),指定不能导入JQuery,因此只能使用原生的Ajax代码发送请求
GET function AjaxGETSubmit1() { var xhr = new XMLHttpRequest(); //回调函数,相当于success: xhr.onreadystatechange = function(){ //回调函数根据状态执行,状态值readyState //0-未初始化,尚未调用open()方法; //1-启动,调用了open()方法,未调用send()方法; //2-发送,已经调用了send()方法,未接收到响应; //3-接收,已经接收到部分响应数据; //4-完成,已经接收到全部响应数据; if (xhr.readyState == 4) { //接收服务端返回的数据 console.log(xhr.responseText) } }; //创建连接 xhr.open('GET','/ajax1.html'); xhr.send(null) } POST function AjaxPOSTSubmit() { var xhr = new XMLHttpRequest(); //回调函数,相当于success: xhr.onreadystatechange = function(){ //回调函数根据状态执行,状态值readyState //0-未初始化,尚未调用open()方法; //1-启动,调用了open()方法,未调用send()方法; //2-发送,已经调用了send()方法,未接收到响应; //3-接收,已经接收到部分响应数据; //4-完成,已经接收到全部响应数据; if (xhr.readyState == 4) { //接收服务端返回的数据 console.log(xhr.responseText) } }; //创建连接 xhr.open('POST','/ajax1.html'); //POST传递时需要,设置请求头 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); xhr.send("p=456") }
from django.shortcuts import render,HttpResponse def ajax1(request): print(request.GET) print(request.POST) print(request.body) ret = {'status':True,'message':'....'} import json return HttpResponse(json.dumps(ret))
“伪”Ajax(iframe标签+form)
iframe标签可以通过不更新界面的情况下,跨域请求
方式一: <h3>伪Ajax提交</h3> <div> <h6>基于Iframe + form表单</h6> <iframe id="iframe" name="ifra" onload="reloadIframe(this)"></iframe> <form id="fm" action="/ajax1.html" method="POST" target="ifra"> <input name="root" value="chen" /> <a onclick="AjaxSubmit()">提交</a> </form> </div> <script> function AjaxSubmit() { document.getElementById('fm').submit(); } //相当于回调函数 function reloadIframe(ths) { //this=当前标签 //基于document来 console.log(ths); console.log(ths.contentWindow); console.log(ths.contentWindow.document.body.innerHTML); //基于JQuery来找 console.log($(ths).contents().find('body').html()); var content = ths.contentWindow.document.body.innerHTML; var obj = JSON.parse(content); if(obj.status){ alert(obj.message); } } </script>
方式二:(推荐) <h3>伪Ajax提交</h3> <div> <h6>基于Iframe + form表单</h6> <iframe id="iframe" name="ifra"></iframe> <form id="fm" action="/ajax1.html" method="POST" target="ifra"> <input name="root" value="chen" /> <a onclick="AjaxSubmit()">提交</a> </form> </div> <script> function AjaxSubmit() { document.getElementById('iframe').onload = reloadIframe; document.getElementById('fm').submit(); } //相当于回调函数 function reloadIframe() { var content = this.contentWindow.document.body.innerHTML; var obj = JSON.parse(content); if(obj.status){ console.log(obj.message) } } </script>
from django.shortcuts import render,HttpResponse def ajax1(request): print(request.GET) print(request.POST) print(request.body) ret = {'status':True,'message':'....'} import json return HttpResponse(json.dumps(ret))
Ajax上传文件
使用formData对象来封装数据
<h3>文件上传</h3> <div> <input type="file" id="img" /> <a class="btn" onclick="AjaxFileSubmit1();">上传</a> <a class="btn" onclick="AjaxFileSubmit2();">上传</a> </div> <script> //Jquery+formData function AjaxFileSubmit1() { var data = new FormData(); data.append('k1','v1'); data.append('k2','v3'); data.append('k3',document.getElementById('img').files[0]); $.ajax({ url:'/ajax1.html', type:'POST', data: data, success:function (arg) { console.log(arg) }, processData:false, contentType:false }) } //原生XMLHttpRequest function AjaxFileSubmit2() { var data = new FormData(); data.append('k1','v1'); data.append('k2','v3'); data.append('k3',document.getElementById('img').files[0]); var xhr = new XMLHttpRequest(); //回调函数,相当于success: xhr.onreadystatechange = function(){ //回调函数根据状态执行,状态值readyState //0-未初始化,尚未调用open()方法; //1-启动,调用了open()方法,未调用send()方法; //2-发送,已经调用了send()方法,未接收到响应; //3-接收,已经接收到部分响应数据; //4-完成,已经接收到全部响应数据; if (xhr.readyState == 4) { //接收服务端返回的数据 console.log(xhr.responseText); } }; //创建连接 xhr.open('POST','/ajax1.html'); xhr.send(data); } </script>
from django.shortcuts import render,HttpResponse def ajax1(request): print(request.GET) print(request.POST) print(request.FILES) ret = {'status':True,'message':'....'} import json return HttpResponse(json.dumps(ret))
iframe标签+form(推荐)
<iframe id="iframe" name="ifra" style="display: none"></iframe> <form id="fm" action="/ajax1.html" method="POST" target="ifra" enctype="multipart/form-data"> <input type="text" name="chen1" /> <input type="text" name="chen2" /> <input type="file" name="chen3" /> <a onclick="AjaxFileSubmit()">提交</a> </form> <script> function AjaxFileSubmit() { document.getElementById('iframe').onload = reloadIframe; document.getElementById('fm').submit(); } //相当于回调函数 function reloadIframe() { var content = this.contentWindow.document.body.innerHTML; var obj = JSON.parse(content); console.log(obj.message) } </script>
jsonp
Ajax发送跨区请求,返回的响应,因为浏览器的同源策略(XMLHttpRequest支持)而被拦截,因此可以默认通过XMLHttpRequest方式发的请求是无法做到跨域请求的。
jsonp.html:1 Access to XMLHttpRequest at 'http://127.0.0.1:8002/chen.html?nid=2' from origin 'http://127.0.0.1:8001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
因此为了避免使用XMLHttpRequest能发送请求,而使用<img src="">和<script src="">来引入网上的图片和script库(bootstrap库)是没有遵循同源机制。
jsonp是一种语言规范
应用A function submitJsonp() { $.ajax({ url:'http://127.0.0.1:8002/chen.html', type:'GET', dataType:'jsonp', //传送过去的是方法名 http://127.0.0.1:8002/chen.html?callback=list jsonp:'callback', jsonpCallback:'list', }) } function list(arg) { console.log(arg) } 应用B def chen(request): name = request.GET.get('callback') return HttpResponse('%s("test2返回");'%(name,))