[Python自学] day-23 (原生Ajax)

一、原生Ajax

在之前学习jQuery的时候,我们选择使用1.x版本,而没有选择使用2.x、3.x版本。

主要是因为1.x版本兼容以前比较老的浏览器,例如IE6 IE7等。

例如要使用Ajax,低版本的浏览器可能不支持xmlHttpRequest对象,而只支持另外一种IE使用的对象叫ActiveXObject。

在jQuery 1.x中,jquery.ajax会对这两种对象进行上层封装,也就是说两种都支持。

但在2.x和3.x中,jquery就放弃了低版本的浏览器,而只支持XHR对象

 

1.使用原生Ajax(GET请求)

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Ajaxtitle>
head>
<body>
<input type="text"/>
<input type="button" value="Ajax" onclick="send_ajax();"/>
<script>
    // onclick事件,发送原生ajax请求
    function send_ajax() {
        // 创建一个xhr对象
        var xhr = new XMLHttpRequest();
        // 建立异步连接,第三个参数true表示异步
        xhr.open('GET', '/ajaxproc/', true);
        // 指定回调函数,每当readystate的值改变时,function就会被执行,当readystate为4时表示收到返回的数据
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                // 打印收到的数据
                console.log(xhr.responseText);
                // 打印收到的状态码,这个码是由视图函数HttpResponse(status=200)返回
                console.log(xhr.status);
                // 打印状态码对应的文本,HttpResponse(reason='文本')返回
                console.log(xhr.statusText);
            }
        };
        // 发送数据
        xhr.send("username=root;password=123456");
    }
script>
body>
html>

 

2.使用原生Ajax(POST请求)

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Ajaxtitle>
head>
<body>
<input type="text"/>
<input type="button" value="Ajax" onclick="Ajax1();"/>
<script>
    // onclick事件,发送原生ajax请求
    function Ajax1() {
        // 创建一个xhr对象
        var xhr = new XMLHttpRequest();
        // 建立异步连接,第三个参数true表示异步
        xhr.open('POST', '/ajaxproc/', true);
        // 指定回调函数,每当readystate的值改变时,function就会被执行,当readystate为4时表示收到返回的数据
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                // 打印收到的数据
                console.log(xhr.responseText);
                // 打印收到的状态码,这个码是由视图函数HttpResponse(status=200)返回
                console.log(xhr.status);
                // 打印状态码对应的文本,HttpResponse(reason='文本')返回
                console.log(xhr.statusText);
            }
        };
        // 要发post请求,必须设置请求头
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
        // 主要要设置csrf,这里省略,参考CSRF章节
        // 发送数据
        xhr.send("username=root;password=1234;");
    }
script>
body>
html>

3.对应视图函数

def ajax(request):
    return render(request, 'ajax.html')


def ajaxproc(request):
    import json
    def check_data(u, p):
        if u == 'leo' and p == '123456':
            return True
        else:
            return False
    if request.method == 'GET':
        if check_data(request.GET.get('username'), request.GET.get('password')):
            ret = {'code': 2000, 'data': "正确"}
        else:
            ret = {'code': 4000, 'data': "错误"}
        return HttpResponse(json.dumps(ret), status=200, reason="OK")
    if request.method == 'POST':
        if check_data(request.POST.get('username'), request.POST.get('password')):
            ret = {'code': 2000, 'data': "正确"}
        else:
            ret = {'code': 4000, 'data': "错误"}
        return HttpResponse(json.dumps(ret), status=200, reason="OK")

4.AJAX返回结果

[Python自学] day-23 (原生Ajax)_第1张图片

 

二、XMLHttpResponse对象介绍

1.XMLHttpResponse对象的主要方法

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()

    终止请求

2.XMLHttpResponse对象的主要属性

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...

 

三、兼容性(跨浏览器支持

主要针对旧版本IE浏览器和chrome浏览器之间的兼容。

XmlHttpRequest
  IE7+, Firefox, Chrome, Opera, etc.

ActiveXObject("Microsoft.XMLHTTP")

  IE6, IE5

 

如果我们想兼容低版本的IE浏览器,也就说当没有XMLHttpResponse的时候,使用ActiveXObject。

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Ajaxtitle>
head>
<body>
<input type="text"/>
<input type="button" value="Ajax" onclick="Ajax1();"/>
<script>
    // 获取XHR
    function getXHR(){
        var xhr=null;
        if (XMLHttpRequest){
            xhr = new XMLHttpRequest();
        }else{
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    // onclick事件,发送原生ajax请求
    function Ajax1() {
        // 创建一个xhr对象
        var xhr = getXHR();
        // 建立异步连接,第三个参数true表示异步
        xhr.open('POST', '/ajaxproc/', true);
        // 指定回调函数,每当readystate的值改变时,function就会被执行,当readystate为4时表示收到返回的数据
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                // 打印收到的数据
                console.log(xhr.responseText);
                // 打印收到的状态码,这个码是由视图函数HttpResponse(status=200)返回
                console.log(xhr.status);
                // 打印状态码对应的文本,HttpResponse(reason='文本')返回
                console.log(xhr.statusText);
            }
        };
        // 要发post请求,必须设置请求头
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
        // 主要要设置csrf,这里省略,参考CSRF章节
        // 发送数据
        xhr.send("username=root;password=1234;");
    }
script>
body>
html>

 

四、jQuery的Ajax

在前面我们已经使用过jQuery封装的Ajax。参照:[Python自学] day-20 (Django-ORM、Ajax) 第三节。

function Ajax1(){
    $.ajax({
        url: '/ajaxproc/',
        type: 'POST',
        data: {'username':'leo','password':'123456'},
        success:function(data,str,xhr_obj) {
            console.log(data);
            console.log(typeof(str)); //打印success(string)
            console.log(xhr_obj);
        }
    })
}

假设我们使用jQuery.ajax,我们所定义的回调函数其实可以接收三个参数。第一个参数data就是服务器的返回值response。第二个参数返回的是一个字符串,成功返回'success'。

第三个参数很关键,他其实就是返回的$.ajax底层调用的XMLHttpResponse对象,也就是原生Ajax中我们new出来的xhr对象。

那就意味着,我们的全部数据都可以从xhr_obj这个参数中去获取:

function Ajax1(){
    $.ajax({
        url: '/ajaxproc/',
        type: 'POST',
        data: {'username':'leo','password':'123456'},
        success:function(data,str,xhr_obj) {
            console.log(xhr_obj.responseText);
            console.log(xhr_obj.status);
            console.log(xhr_obj.statusText);
        }
    })
}

查看打印结果:

[Python自学] day-23 (原生Ajax)_第2张图片

可以看到,这和原生Ajax一模一样。

 

五、伪Ajax

1.认识iframe标签

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Iframetitle>
head>
<body>
<iframe id="ifm" src="http://www.baidu.com" style="height: 400px;width: 800px;">iframe>
<input id='ifm_url' type="text"/>
<input type="button" value="发送" onclick="iframe_send();"/>
<script src="/static/jquery-1.12.4.js">script>
<script>
    function iframe_send(){
        var url = $("#ifm_url").val();
        console.log(url);
        $("#ifm").attr('src',url);
    }
script>
body>
html>

页面效果:

[Python自学] day-23 (原生Ajax)_第3张图片

 

可以看到,中间的百度页面就是iframe标签。因为