前端笔记——ajax学习

一、前置知识点

1. 关于AJAX

  • AJAX全称Asynchronous Javascript And XML(异步JS和XML),可以不在刷新整个网页的前提下,对局部进行更新。

2. 关于HTTP

1)HTTP请求的组成(详情)
  • 共有四部分组成:请求行、请求头部、空行、请求数据
2)常见请求方法(详情)
  • GET: 请求指定的页面信息,并返回实体主体;
  • POST: 向指定资源提交数据进行处理请求。
3)常见响应状态码(详情)
  • 200:请求成功;
  • 301:资源(网页等)被永久转移到其它URL;
  • 404:请求的资源(网页等)不存在;
  • 500:内部服务器错误。

二、对一个基本AJAX的操作进行概括

  1. 绑定:获取一个页面元素并为其绑定上一个事件;
  2. 发送http请求:在事件中,创建AJAX对象,初始化该对象(设置好url和请求方法)并发送
  3. 接收并完成刷新:处理服务端响应的结果,成功获得内容后,刷新相应的网页部分。
// 1. 绑定:获取一个页面元素并为其绑定上一个事件
const result = document.getElementById("result"); 
result.addEventListener("mouseover", function(){
    // 2. 发送http请求:在事件中,创建AJAX对象,初始化该对象(设置好http请求信息)并发送;
    const xhr = new XMLHttpRequest(); 
    xhr.open('POST', 'http://127.0.0.1:8000/server'); 
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.send('a=100&b=200&c=300'); 
    // 3. 接收并完成刷新:处理服务端响应的结果,成功获得内容后,刷新相应的网页部分
    xhr.onreadystatechange = function() {
        if(xhr.readyState === 4) { // 完全收到信息
            if(xhr.status >= 200 && xhr.status < 300) { // 服务起成功响应并返回数据 
                result.innerHTML = "xhr.response"; 
            }
        }
    }
}); 

三、AJAX设置HTTP请求

  1. 请求行的设置,主要在send方法中实现,设置好请求方法和URL信息,如:“xhr.open('GET', 'http://127.0.0.1:8000/server')”;
  2. 请求头的设置,使用函数“setRequestHeader("请求头部字段名", "值")”;
  3. 请求数据的设置,对于GET方法,请求数据可以附在URL信息后面,如:“xhr.open('GET', 'http://127.0.0.1:8000/server?请求数据')”; 对于POST方法,请求数据可以在作为send方法的参数发送过去,如:“xhr.send('请求数据')”。

四、JSON数据

1. 服务端

响应发送JSON数据时需要先将设置好的对象用JSON.Stringify()方法转换为字符串再发送。

2. 客户端

接收到数据,有两种方法将字符串重新变成对象:

  • 设置xhr.responsetype="json",这样会将接收到的字符串自动转换为对象;
  • 先接收字符串数据,然后使用JSON.parse()方法,手动将字符串转换为对象。
// 服务端例子,使用express框架
var express = require('express'); 
var app = express(); 
app.get("/json-server", function(req, res) {
    res.setHeader("Access-Control-Allow-Origin", '*'); 
    res.setHeader("Access-Control-Allow-Headers", '*'); 
    // **************创建一个对象,并将其转换为字符串*************
    const data = {
        name: "asldkfjdsal"
    }; 
    var str = JSON.stringify(data); // 将对象转换为字符串
    // *******************************************************
    res.send(data); 
    console.log("json-server send: ", str); 
})

var server = app.listen("8000", function() {
    console.log("服务启动,地址http://127.0.0.1:8000"); 
})
<!-- 客户端例子 -->
<!DOCTYPE html>
<html>
    <head>
        <title>JSON 响应</title> <!-- 显示json数据中的"name"属性值 -->
        <style>
            #result {
                width: 200px; 
                height: 100px; 
                border: solid 1px grey; 
            }
        </style>
    </head>
    <body>
        <div id="result"></div>
        <script>
            var result = document.getElementById("result"); 
            window.onkeydown = function() {
                const xhr = new XMLHttpRequest(); 
                // *******设置好这个属性会自动转换json数据*********
                xhr.responseType = "json"; 
                // *********************************************
                xhr.open("get", "http://127.0.0.1:8000/json-server"); 
                xhr.send(); 
                xhr.onreadystatechange = function() {
                    if(xhr.readyState === 4) {
                        if(xhr.status >= 200 && xhr.status < 300) {
                            /* *****************手动转换数据*****************************
                            var data = JSON.parse(xhr.response); // 将字符串重新变成对象
                            result.innerHTML = data.name; 
                            *********************************************************** */
                            // 已经自动转换数据,直接使用 
                            console.log(xhr.response); 
                            result.innerHTML = xhr.response.name; 
                        }
                        
                    }
                }
            }
        </script>
    </body>
</html>

五、IE缓存问题

老版ie会缓存AJAX数据,在时效性要求高的情况下容易出问题,解决方法是在请求的url后面添加不断变化的的参数,如“open("get", "http://127.0.0.1:8000?t="+Date.now());”。

六、请求超时和异常处理(在“初始化”步骤中实现)

1. 请求超时处理

xhr.timeout = 2000; // 设置2s之后没有响应就取消请求 
xhr.onouttime = function() { // 请求一旦超时就调用这个函数 
    // 代码
};
// 服务端可以利用setTimeout()方法来模拟请求超时的情况
setTimeout(function() {
      res.send();
}, 3000); // 延时3s执行

2. 异常处理

xhr.onerror = function() { // 网络出现异常(如断网)就调用这个函数
    // 代码
};

七、取消请求及其应用

1. 取消请求

// 在客户端肯带响应时可以使用abort()来取消手动。
<!DOCTYPE html>
<html>
    <head>
        <title>6-取消请求</title>
        <style>

        </style>
    </head>
    <body>
        <button>发送请求</button>
        <button>取消请求</button>
        <script>
            const btns = document.getElementsByTagName("button"); 
            var x = null;

            btns[0].onclick = function() {
                x = new XMLHttpRequest(); 
                x.open("get", "http://127.0.0.1:8000/delay"); 
                x.send(); 
            }; 
            // *********************************
            btns[1].onclick = function() {
                x.abort(); 
            }
            // *********************************
        </script>
    </body>
</html>

2. 防止客户端短时间内重复发送相同的请求

<!DOCTYPE html>
<html>
    <head>
        <title>7-重复请求</title>
    </head>
    <body>
        <button>发送请求</button>
        <script>
            const btns = document.getElementsByTagName("button"); 
            var xhr = null; 
            // *************************************************
            isSending = false; // 记录状态,是否在发送请求
            btns[0].onclick = function() { // 
                if(isSending) {
                    xhr.abort(); // 先判断是否在发送状态,是的话取消上一次的请求
                    isSending = false; 
                }
 
                xhr = new XMLHttpRequest(); 
                isSending = true; // 进入发送状态 
                xhr.open("get", "http://127.0.0.1:8000/delay"); 
                xhr.send(); 
                xhr.onreaystatechange = function() {
                    if(x.readyState === 4) { // 完全接收数据
                        isSending = false; // 发送状态结束
                    }
                }; 
            }; 
            // *************************************************
        </script>
    </body>
</html>
posted @ 2020-12-11 21:25  叶落未落  阅读(141)  评论(0)    收藏  举报