AJAX学习-2

AJAX

2.1 服务端响应JSON数据

因为服务器端设置响应体的代码response.send();内只能接受字符串和buffer,所以如果服务器想将一个其它类型的数据返回,就需要使用到JSON知识,server.js中添加的代码如下所示:

// all请求可以接受任意类型的请求
app.all('/json-server',(request,response)=>{
    // 设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 响应头  设置允许所有的请求头
    response.setHeader('Access-Control-Allow-Headers','*');
    // 响应一个数据
    const data = {
        name: 'atguigu'
    };
    // 对对象进行字符串的转换
    // let用来声明局部变量
    let str = JSON.stringify(data);
    // 设置响应体 只能接受字符串和buffer
    response.send(str);
});

HTML\CSS\JAVASCRIPT代码如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #result{
            width: 200px;
            height: 100px;
            border: solid 1px black;
        }
    </style>
</head>
<body>
    <div id="result"></div>
    <script>
        const resulst = document.getElementById("result");
        window.onkeydown = function(){
            // 1.创建对象
            const xhr = new XMLHttpRequest();
            //设置响应体数据的类型
            xhr.responseType = 'json';
            // 2.初始化 请求类型和url
            xhr.open("GET",'http://127.0.0.1:8000/json-server');
            // 3.发送
            xhr.send();
            // 4.事件绑定
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    if(xhr.status >=200 && xhr.status < 300){
                        //console.log(xhr.response);
                        //resulst.innerHTML = xhr.response;
                        // 手动对数据转化
                        //let data = JSON.parse(xhr.response);
                        //console.log(data);
                        console.log(xhr.response);
                        // 自动转换
                        resulst.innerHTML =xhr.response.name;
                    }
                }

            }
        }

    </script>
</body>
</html>

JSON的stringify可以将一个其他类型的数据转化为JSON字符串,JSON的parse可以将JSON字符串转化为原始数据,这也是我们手动转换的原理.
第二种处理JSON字符串的方式是自动处理,我们在创建完对象以后,设置响应体数据的类型:

//设置响应体数据的类型
xhr.responseType = 'json';

这样我们就可以直接在网页端得到自动转换后响应的数据了,最终效果如下所示:
image

2.2 AJAX中IE缓存问题解决

AJAX在IE浏览器中会存在缓存问题,即服务器端修改了响应体内容,但是IE浏览器不能及时响应,此时我们可以给url加一个时间戳来解决:
xhr.open("GET","http://127.0.0.1:8000/ie?t="+ Date.now());
?t=代表的是一个时间格式的内容,Date.now()可以获取到从1970年1月1日到现在过的秒数,即时间戳,这样就可以每次点击的时候生成一个不同时间戳的内容,从而保证及时响应.

2.3 AJAX请求超时和网络异常处理

首先我们先给服务端设置一个延时响应处理,代码如下:

//延迟响应
app.get('/delay',(request,response)=>{
    // 设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    setTimeout(() => {
        //设置响应体
        response.send("延时响应");
    }, 3000);
});

其中setTimeOut是延时响应的核心代码,第一个参数为函数,第二个参数为延时时间,单位为毫秒.
然后我们就可以在创建对象后进行超时设置\超时回调和网络异常回调,相关的JS代码如下:

<script>
	const btn = document.getElementsByTagName("button")[0];
const result = document.getElementById("result");

btn.addEventListener("click",function(){
	const xhr = new XMLHttpRequest();
	// 超时设置
	xhr.timeout = 2000;
	// 超时回调
	xhr.ontimeout = function(){
		alert("网络异常,请稍后重试!!");
	}
	// 网络异常回调
	xhr.onerror = function(){
		alert("你的网络似乎出了一些问题!");
	}
	xhr.open("GET","http://127.0.0.1:8000/delay");
	xhr.send();
	xhr.onreadystatechange = function(){
		if(xhr.readyState == 4){
			if(xhr.status >= 200 && xhr.status < 300){
				result.innerHTML = xhr.response;
			}
		}
	}
});
</script>

网络异常回调可以在开发者工具中,Network栏中Online改为Offline进行测试,测试完毕后再修改回去就可以了.

2.4 AJAX取消请求

在JS中我们可以使用abort()函数来取消发送请求,具体例子如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>取消请求</title>
    <style></style>
</head>
<body>
    <button type="button">发送请求</button>
    <button type="button">点击取消</button>
    <script>
        // 获取元素对象
        const btn1 = document.getElementsByTagName("button")[0];
        const btn2 = document.getElementsByTagName("button")[1];
        let x = null;

        // 发送请求
        btn1.onclick = function(){
            x = new XMLHttpRequest();
            x.open("GET","http://127.0.0.1:8000/delay");
            x.send();
        }

        // abort()函数来取消
        btn2.onclick = function(){
            x.abort();
        }
    </script>
</body>
</html>

2.5 AJAX重复发送请求问题

如果一个用户频繁操作来发送请求,很有可能给服务器造成负担,因此我们必须要解决AJAX重复发送请求的问题,让用户发送相同的新请求时,把之前的请求取消掉,我们可以设置一个局部变量isSending()作为标识变量,结合上一节的知识,很容易写出逻辑:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>重复请求问题</title>
    <style></style>
</head>
<body>
    <button type="button">发送请求</button>
    <script>
        // 获取元素对象
        const btn1 = document.getElementsByTagName("button")[0];
        let x = null;
        // 标识变量
        let isSending = false;

        // 发送请求
        btn1.onclick = function(){
            //判断标识变量
            if(isSending){
                //如果正在发送,则取消该请求,创建一个新请求
                x.abort();
            }
            x = new XMLHttpRequest();
            //修改标识变量的值
            isSending = true;
            x.open("GET","http://127.0.0.1:8000/delay");
            x.send();
            x.onreadystatechange = function(){
                if(x.readyState == 4){
                    //修改标识变量
                    isSending = false;

                }
            } 
        }
    </script>
</body>
</html>

image

posted @ 2021-09-27 15:57  bleaka  阅读(66)  评论(0)    收藏  举报