Ajax的学习

概述

Web程序最初的目的就是将信息(数据)放到公共的服务器,让所有网络用户都可以通过浏览器访问。

在此之前,我们可以通过以下几种方式让浏览器发出对服务端的请求,获得服务端的数据:

●地址栏输入地址,回车,刷新

●特定元素的href或src属性

●表单提交

这些方案都是我们无法通过或者很难通过代码的方式进行编程(对服务端发出请求并且接受服务端返回的响应),如果我们可以通过JavaScript直接发送网络请求,那么Web的可能就会更多,随之能够实现的功能也会更多,至少不再是”单机游戏”。

AJAX( Asynchronous JavaScript and XML ) ,(先前是服务器返回XML,现在返回的是JSON格式,所以实际上该技术是AJAJ) 最早出现在2005年的Google Suggest (就是搜索框下的建议列表),是在浏览器端进行网络编程(发送请求、接收响应)的技术方案,它使我们可以通过JavaScript直接获取服务端最新的内容而不必重新加载页面。让Web更能接近桌面应用的用户体验。

AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

说白了, AJAX就是浏览器提供的一套API ,可以通过JavaScript调用,从而实现通过代码控制请求与响应。实现网络编程。能力不够,API来凑。

AJAX发送请求

XMLHttpRequest:

程序必须先调用XMLHt tpRequest对象的responseText或responseXML来获取服务器响应,再通过DOM操作将服务器响应动态加载到当前页面中。

关于XMLHttpRequest最通用的定义是: XMLHttpRequest是一套可以在JavaScript、VBscript、JScript 等脚本语言中使用的API,它通过HTTP协议异步地向服务器发送请求,并获取从服务器返回的响应。

涉及到 ajax 操作的页面“不能”使用文件协议访问。(不能文件的方式访问)

(我放在了phpstudy_pro里www里的域名为ajax.learn 端口为8080的站点里

所以在网址输入ajax.learn:8080/ajax/ajax1.html就行了)

        // 1.安装浏览器(浏览器相当于用户代理)
        // xhr 就类似于浏览器的作用(发送请求接收响应)
        var xhr = new XMLHttpRequest();
        // 2. 打开浏览器,输入网址
        xhr.open('GET', 'time.php');
        // 3. 敲回车,开始请求
        xhr.send();        //在检查里的network中all可查看向服务器请求回的

oneadytatechange事件中获取响应内容

        // 1.安装浏览器(浏览器相当于用户代理)
        // xhr 就类似于浏览器的作用(发送请求接收响应)
        var xhr = new XMLHttpRequest();
        // 2. 打开浏览器,输入网址
        xhr.open('GET', 'time.php');
        // 3. 敲回车,开始请求
        xhr.send();
        // 4. 等待响应
        // 因为响应需要时间,所以无法通过返回值的方式返回响应 即不能console.log(xhr.send());
        // 因为客户端永远不知道服务端何时才能返回我们需要的响应
        // 所以AJAX API采用事件的机制(通知的感觉)
        xhr.onreadystatechange = function () {
            //这个事件并不是只在响应时触发, 状态改变就触发,(状态改变即创建xhr、open、send)
            console.log(1);   //所以打印了3个1
            console.log(this.readyState);   //2 3 4  因为每个状态对应一个数,0代表创建xhr,1代表open。。。   但是由于事件是后触发的,所以没有打印出全部,
//如果需要捕获第一个状态的变化,需要注意代码执行顺序的问题(不要出现来不及的情况)
        }

time.php

<?php
echo time();
?> 

readyState有五种可能的值:

0 (未初始化): (XMLHttpRequest)对象已经创建,但还没有调用open()方法。

1 (载入):已经调用open() 方法,但尚未发送请求。

2 (载入完成): 请求已经发送完成。

3 (交互):可以接收到部分响应数据。

4 (完成):已经接收到了全部数据,并且连接已经关闭。

        // 1.安装浏览器(浏览器相当于用户代理)
        // xhr 就类似于浏览器的作用(发送请求接收响应)
        var xhr = new XMLHttpRequest();
        console.log(xhr.readyState);   // => 0 初始化,请求代理对象
        // 2. 打开浏览器,输入网址
        xhr.open('GET', 'time.php');
        console.log(xhr.readyState);   // => 1 open方法已经调用,建立一个与服务端特定端口的连接
        // 3. 敲回车,开始请求
        xhr.send();
        // 4. 等待响应
        // 因为响应需要时间,所以无法通过返回值的方式返回响应 即不能console.log(xhr.send());
        // 因为客户端永远不知道服务端何时才能返回我们需要的响应
        // 所以AJAX API采用事件的机制(通知的感觉)
        xhr.onreadystatechange = function () {
            //这个事件并不是只在响应时触发, 状态改变就触发,(状态改变即创建xhr、open、send)
            // console.log(1);   //所以打印了3个1
            // console.log(this.readyState);   //2 3 4
            // switch (this.readyState) {
            //     case 2:
            //         console.log(this.readyState);
            //         // => 2  已经接受到了响应报文的响应头,即服务器名称信息等,但没有接受到响应体
            //         console.log(this.getAllResponseHeaders());  //打印响应头
            //         break;
            //     case 3:
            //         console.log(this.readyState);
            //         // => 3  正在下载响应报文的响应体,有可能为空、或不完整、或完整。
            //         break;
            //     case 4:
            //         console.log(this.readyState);
            //         // => 4  响应体下载完成
            //         break;
            // }
            if (this.readyState !== 4) return;
            //若状态是4,则获取响应的内容
            // console.log(this.readyState);  //4
            console.log(this.responseText);   //1618626395  ,即我们请求的time.php中返回的数据
        }

onload事件

        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'time.php');
        xhr.send();
        
        // onl oad是HTML5 中提供的XMLHttpRequest version 2.0定义的,跟上述一样的功能
        xhr.onload = function () {
            console.log(this.readyState);   //4
            console.log(this.responseText);  //1618630324
        }

ajax遵循HTTP协议

        var xhr = new XMLHttpRequest();
        xhr.open('POST', 'add.php');  //设置请求行
        xhr.setRequestHeader('Foo', 'Bar');  //设置一个请求头
        // 一定注意 如果请求体是urlencoded格式必须设置这个请求头
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.send('key1=value1&key2=value2');  //以urlencoded 格式设置请求体

add.php

<?php
var_dump($_POST);
?>

数据接口的概念

users1.php

<?php
// 返回的响应就是一个JSON 内容(返回的就是数据)
// 对于返回数据的地址一般我们称之为接口(形式上是Web信息)
$data = array(
    array(
        'id' => 1,
        'name' => '束文波'
    ),
    array(
        'id' => 2,
        'name' => '小夏'
    ),
    array(
        'id' => 3,
        'name' => '米卡'
    ),
    array(
        'id' => 4,
        'name' => '邢克垒'
    )
);
if (empty($_GET['id'])) {
    // 没有传ID,则获取全部
    // 因为HTTP中约定报文的内容就是字符串,而我们需要传递给客户端的信息是-个有结构的数据
    // 这种情况下我们一般采用JSON作为数据格式
    $json = json_encode($data);// 格式:[{"id":1,"name":"束文波"},{...}]
    echo $json; 
} else {
    // 传递了ID,只获取一条
    foreach ($data as $item) {     //循环遍历,
        if ($item['id'] != $_GET['id']) continue;   //找到对应的id对应的数组
        $json = json_encode($item);
        echo $json;   //在地址栏设id=1,则打印出{"id":1,"name":"\u675f\u6587\u6ce2"} ,其中汉字是Unicode格式
    }
}

发送GET请求并传递参数

        var xhr = new XMLHttpRequest();
        // 这里仍然是使用URL中的问号参数传递数据
        xhr.open('GET', 'users.php?id=3');   //users.php在上面 在这里填京东啊,爱奇艺什么的相关数据接口,在下面即可获取内容
        xhr.send(null); 
        xhr.onreadystatechange = function () {
            if (this.readyState !== 4) return;
            console.log(this.responseText);   //{"id":3,"name":"\u7c73\u5361"}
        }

发送GET请求并传递参数—小例子

user2.php

<?php
// 返回的响应就是一个JSON 内容(返回的就是数据)
// 对于返回数据的地址一般我们称之为接口(形式上是Web信息)
$data = array(
    array(
        'id' => 1,
        'name' => '束文波',
        'age' => 26
    ),
    array(
        'id' => 2,
        'name' => '小夏',
        'age' => 24
    ),
    array(
        'id' => 3,
        'name' => '米卡',
        'age' => 23
    ),
    array(
        'id' => 4,
        'name' => '邢克垒',
        'age' => 29
    )
);
if (empty($_GET['id'])) {
    // 没有传ID,则获取全部
    // 因为HTTP中约定报文的内容就是字符串,而我们需要传递给客户端的信息是-个有结构的数据
    // 这种情况下我们一般采用JSON作为数据格式
    $json = json_encode($data);   // 格式: [{"id":1,"name":"张三"},{...}]
    echo $json; 
} else {
    // 传递了ID,只获取一条
    foreach ($data as $item) {     //循环遍历,
        if ($item['id'] != $_GET['id']) continue;   //找到对应的id对应的数组
        $json = json_encode($item);
        echo $json; //在地址栏设id=1,则打印出{"id":1,"name":"\u675f\u6587\u6ce2"} ,其中汉字是Unicode格式
    }
}

实现:点击名字,弹出相应年龄。

<body>
    <ul id="list"></ul>
    <script>
        var listElement = document.getElementById('list');
        // 发送请求获取列表数据呈现在页面
        var xhr1 = new XMLHttpRequest();
        xhr1.open('GET', 'users1.php');
        xhr1.send();
        xhr1.onreadystatechange = function () {
            if (this.readyState !== 4) return;
            //使用 JSON.parse() 方法将请求到的 JSON 数据转换为 JavaScript 对象
            var data = JSON.parse(this.responseText);
            //循环遍历,为每个li注册点击事件
            for (var i = 0; i < data.length; i++) {
                // 创建多个元素li
                var liElement = document.createElement('li');
                // 给li标签设置内容为传过来的name的值
                liElement.innerHTML = data[i].name;
                liElement.id = data[i].id;
                // 把li添加到ul中
                listElement.appendChild(liElement);
                
                // 为li注册点击事件
                listElement.children[i].addEventListener('click', function () {
                    // 需要再请求个数据,返回本次点击的响应的数据
                    var xhr2 = new XMLHttpRequest();
                    // id为本次点击的名字的id
                    xhr2.open('GET', 'users2.php?id=' + this.id);
                    xhr2.send();
                    xhr2.onreadystatechange = function () {
                        if (this.readyState !== 4) return;
                        var data2 = JSON.parse(this.responseText);
                        // 弹出相应名字的年龄
                        alert(data2.age);
                    }
                })
            }
        }

    </script>
</body>

发送POST请求

POST请求过程中,都是采用请求体承载需要提交的数据。

如: xhr.send(‘username=KaTeX parse error: Expected 'EOF', got '&' at position 11: {username}&̲password={password}’);

login.php

<?php
// 接收用户提交的用户名和密码
if (empty($_POST['username']) || empty($_POST['password'])) {
    exit('请提交用户名和密码');
}
//校验
$username = $_POST['username'];
$password = $_POST['password'];
if ($username == '蜡笔小新' && $password == 'ilovexiaogege') {
    exit('成功登录');
}
exit('用户名或密码错啦');
?>

实现 点击登录按钮,显示加载层,加载完成后,打印结果

    <style>
        .loading {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgb(128, 125, 125);
            opacity: 0.5;
            text-align: center;
            line-height: 500px;
            font-size: 50px;
            display: none;
        }
        .loading::after {
            /*::after用来创建一个伪元素,作为已选中元素的最后一个子元素。这个虚拟元素默认是行内元素。 */
            content: '加载中...';
            color: #fff;
        }
    </style>
</head>
<body>
    <div class="loading" id="loading"></div>
    <table border="1">
        <tr>
            <td>用户名</td>
            <td><input type="text" name="" id="username"></td>
        </tr>
        <tr>
            <td>密码</td>
            <td><input type="password" name="" id="password"></td>
        </tr>
        <tr>
            <td></td>
            <td><button id="btn">登录</button></td>
        </tr>
    </table>
    <script>
        var btn = document.getElementById('btn');
        var txtUsername = document.getElementById('username');
        var txtPassword = document.getElementById('password');
        var loading = document.getElementById('loading');
        // 找一个合适的时机,做一件合适的事情
        btn.onclick = function () {
            //点击登录显示加载中。。。
            loading.style.display = 'block';
            // 1.获取界面上的元素 value
            var username = txtUsername.value;
            var password = txtPassword.value;
            // 2.通过 XHR 发送一个 POST 请求
            var xhr = new XMLHttpRequest();
            xhr.open('POST', 'login.php');
            // 一定注意 如果请求体是urlencoded格式必须设置这个请求头
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.send('username=${username}&password=${password}');
            // 3.根据服务端的反馈 做出界面提示
            xhr.onreadystatechange = function () {
                if (this.readyState !== 4) return;
                //加载完成
                loading.style.display = 'none';
                console.log(this.responseText);    // 用户名或密码错啦
            }
        }
    </script>
</body>

同步与异步

**同步:**一个人在同一个时刻只能做一件事情,在执行一些耗时的操作 ( 需要看管)不去做别的只是等待

**异步:**在执行一些耗时的操作(不需要看管)去做别的事,而不是等待

一般很少用同步。

        //异步
        console.time('aa');
        var xhr = new XMLHttpRequest();
        // open 方法的第三个参数是async异步 可以传入一个布尔值, 默认为true 
        xhr.open('GET', 'time.php', true);
        xhr.send();
        console.log(xhr.responseText);  // 为空 因为异步是同时干好多事,send后的事在执行send时也在做
        // 所以需要:xhr.onreadystatechange = function () 获得完整数据
        console.timeEnd('aa');   // aa: 0.64208984375 ms

        //同步
        console.time('bb');
        var xhr2 = new XMLHttpRequest();
        // open 方法的第三个参数是async异步 可以传入一个布尔值, 默认为true 
        xhr2.open('GET', 'time.php', false);
        xhr2.send();
        // 同步是依次执行,所以不用xhr.onreadystatechange = function () 就能完整接收数据
        console.log(xhr2.responseText);  // 打印出1618828035  
        console.timeEnd('bb');   // bb: 21.026123046875 ms

所以很少用到 同步模式。

响应数据格式

XML

一种数据描述手段

老掉牙的东西,简单演示一下,不在这里浪费时间,基本现在的项目不用了。

淘汰的原因:数据冗余太多

Ajax的学习Ajax的学习

JSON
也是一种数据描述手段,类似于JavaScript字面量方式
服务端采用JSON格式返回数据,客户端按照JSON格式解析数据。
不管是JSON也好,还是XML,只是在AJAX请求过程中用到,并不代表它们之间有必然的联系,它们只是数据协议罢了

处理响应数据渲染
模板引擎:
artTemplate : https://aui.github.io/art-template/
模板引擎实际上就是一个API, 模板引擎有很多种,使用方式大同小异,目的为了可以更容易的将数据渲染到HTML中

兼容方案:
XMLHttpRequest在老版本浏览器( IE5/6 )中有兼容问题,可以通过另外-种方式代替
var xhr = window. XMLHttpRequest ? new XMLHttpRequest() : new ActiveXobject(‘Mi crosoft.XMLHTTP’)
Ajax的学习

<body>
    <table>
        <tbody id="content"></tbody>
    </table>
    <script>
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'test.php');
        xhr.send();
        xhr.onreadystatechange = function () {
            if (this.readyState !== 4) return;

            var res = JSON.parse(this.responseText);

            var data = res.data;
            for (var i = 0; i < data.length; i++) {
                var tr = document.createElement('tr');
                var td = document.createElement('td');
                //下面方式太麻烦,我们采用模板引擎将数据呈现 artTemplate:https://aui.github.io/art-template/  模板引擎实际上就是一个API
                td.innerHTML = '<td>' + data[i].id + '</td>'  
            }
        }
    </script>
</body>
上一篇:VMware Work Station使用ubuntu20.04挂载共享文件夹写入文件时出现输入/输出错误


下一篇:Oracle commonly uesd tables/views and processes(一)