柴少的博客 也许终将一事无成,却不能甘于平庸。

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>

测试一下:

图片.png

#当点击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>

测试一下:

图片.png

#后台也拿到了发送过来的数据。

二、伪Ajax

由于HTML标签的iframe标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求。

#这里主要说的是iframe,先来个小例子:

<iframe id="ifm" src="http://www.baidu.com"></iframe>

图片.png

#可以看到就把百度首页嵌套到标签里面来了。

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>

图片.png

图片.png

这里面有一个地方需要注意就是iframe部分的内容在页面中其实也是一个完整的html,如下所示:

图片.png

#所以通过js操作的时候不能直接找到iframe标签然后text,需要通过contents()获取iframe中的内容,最后通过find找到自己需要的数据,这样当我们点击页面的提交的时候就可以在js中获取返回数据

#如果是发送普通数据,jQuery,XMLHttpRequest,iframe的优先级使用:jQuery---->XMLHttpRequest----->iframe
#如果是发送文件jQuery,XMLHttpRequest,iframe的优先级使用:iframe(伪Ajax) ----> jQuery(FormData) ----> XMLHttpRequest(FormData

作者:chaishaopeng 分类:Django学习 浏览:1437 评论:0
留言列表
发表评论
来宾的头像