Django之Ajax(十五)
一、原生的Ajax
Ajax主要就是使用 XmlHttpRequest对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件)。
1.1 XmlHttpRequest对象介绍
XmlHttpRequest对象的主要方法:
a. void open(String method,String url,Boolen async) 用于创建请求(其实这里既是创建一个连接) 参数: method: 请求方式(字符串类型),如:POST、GET、DELETE... url: 要请求的地址(字符串类型) async: 是否异步(布尔类型) b. void send(String body) 用于发送请求 参数: body: 要发送的数据(字符串类型) c. void setRequestHeader(String header,String value) 用于设置请求头 参数: header: 请求头的key(字符串类型) vlaue: 请求头的value(字符串类型) d. String getAllResponseHeaders() 获取所有响应头 返回值: 响应头数据(字符串类型) e. String getResponseHeader(String header) 获取响应头中指定header的值 参数: header: 响应头的key(字符串类型) 返回值: 响应头中指定的header对应的值 f. void abort() 终止请求,比如发一个ajax请求可能会耗时很久,这个可以主动终止请求。
XmlHttpRequest对象的主要属性:
a. Number readyState 状态值(整数) 详细: 0-未初始化,尚未调用open()方法; 1-启动,调用了open()方法,未调用send()方法; 2-发送,已经调用了send()方法,未接收到响应; 3-接收,已经接收到部分响应数据; 4-完成,已经接收到全部响应数据; b. Function onreadystatechange 当readyState的值改变时自动触发执行其对应的函数(回调函数) c. String responseText 服务器返回的数据(字符串类型) d. XmlDocument responseXML 服务器返回的数据(Xml对象) e. Number states 状态码(整数),如:200、404... f. String statesText 状态文本(字符串),如:OK、NotFound...
来个简单小例子理解一下:
urls.py:
url(r'^ajax/$', views.ajax), url(r'^ajax_json/$', views.ajax_json),
views.py:
def ajax(request): return render(request, 'ajax.html') def ajax_json(request): import time time.sleep(3) print(request.POST) ret = {'code': True , 'data': request.POST.get('username')} import json return HttpResponse(json.dumps(ret))
ajax.html:
<body> <input type="text"> <input type="button" value="Ajax1" onclick="Ajax1();"> <script> function Ajax1() { var xhr = new XMLHttpRequest(); xhr.open("GET","/ajax_json/"); //onreadystatechange其实就是一个回调函数, //只要readyState状态发生变化就会执行, //下面的方法表示只有状态为4是才执行函数下面的内容 xhr.onreadystatechange=function () { if(xhr.readyState == 4){ //表示接收完毕 //responseText其实就是接受的内容 console.log(xhr.responseText); //xhr.responseText就是要拿的返回值 var obj = JSON.parse(xhr.responseText) console.log(obj) } }; //setRequestHeader设置请求头,可以设置csrf xhr.setRequestHeader("k1","v1"); //发送信息 xhr.send("name = root;pwd = 123"); } </script> </body>
测试一下:
#当点击Ajax1提交的时候就会显示标红的内容。
1.2 跨浏览器的问题
上述的是通过GET,下面我们通过讲上述代码中的GET更改为POST,并且这里同时可以设置兼容问题,如微软的IE浏览器里面没有XMLHttpRequest
ajax.html:
<body> <input type="text"> <input type="button" value="Ajax1" onclick="Ajax1();"> <script> //用于兼容微软的IE浏览器 function getXHR(){ var xhr = null; if(XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); //ActiveXObject("Microsoft.XMLHTTP")表示创建了IE特殊的对象,windows没有XMLHttpRequest. } return xhr; } function Ajax1() { var xhr = getXHR(); //getXHR()直接获取对象的返回值 xhr.open("POST","/ajax_json/"); xhr.onreadystatechange=function () { if(xhr.readyState == 4){ //表示接收完毕 console.log(xhr.responseText); var obj = JSON.parse(xhr.responseText) console.log(obj) } }; //通过原生的ajax发送post的请求的时候必须设置请求头,否则发送不到后台 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); xhr.send("name = root;pwd = 123"); } </script> </body>
测试一下:
#后台也拿到了发送过来的数据。
二、伪Ajax
由于HTML标签的iframe标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求。
#这里主要说的是iframe,先来个小例子:
<iframe id="ifm" src="http://www.baidu.com"></iframe>
#可以看到就把百度首页嵌套到标签里面来了。
ajax.html:
<body> <form action="/ajax_json/" method="POST" target="ifml"> <iframe id = "ifml" name="ifml"></iframe> <input type="text" name="username"> <input type="text" name="email"> <input type="submit" name="Form提交" onclick="sumbitForm();"> </form> <script type="text/javascript" src="/static/jquery-1.12.4.js"></script> <script> function sumbitForm() { $("#ifml").load(function () { //当有结果返回的时候会触发load事件,所以这里绑定这个事件 //iframe在html页面中其实在html页面中包含了一个html页面, //及时上下文的关系,所以这里需要 //通过contents()获得iframe中的内容然后通过find找到body中的内容 var text = $("#ifml").contents().find("body").text(); //contents()方法获得匹配元素集合中每个元素的子节点,包括文本和注释节点。 var obj = JSON.parse(text); console.log(obj) }) } </script> </body>
这里面有一个地方需要注意就是iframe部分的内容在页面中其实也是一个完整的html,如下所示:
#所以通过js操作的时候不能直接找到iframe标签然后text,需要通过contents()获取iframe中的内容,最后通过find找到自己需要的数据,这样当我们点击页面的提交的时候就可以在js中获取返回数据
#如果是发送普通数据,jQuery,XMLHttpRequest,iframe的优先级使用:jQuery---->XMLHttpRequest----->iframe
#如果是发送文件jQuery,XMLHttpRequest,iframe的优先级使用:iframe(伪Ajax) ----> jQuery(FormData) ----> XMLHttpRequest(FormData