json数据&nodemon自动重启功能&IE缓存问题&请求超时和网络异常&取消请求&请求重复问题

146 阅读2分钟

json数据&nodemon自动重启功能&IE缓存问题&请求超时和网络异常&取消请求&请求重复问题

json格式数据处理

json.html

<!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>
        .box {
            width: 100px;
            height: 50px;
            border: 1px solid green;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <script>
        var box = document.querySelector('.box');
        // 按下键盘绑定事件
        window.onkeydown=function(){
            const xhr = new XMLHttpRequest();
            // 设置响应体数据的类型 自动数据转化是生成json对象 
            // 注意这里一定要小写
            xhr.responseType = 'json';
            xhr.open('GET','http://localhost:7000/json-server');
            xhr.send();
            xhr.onreadystatechange=function(){
                if(xhr.readyState===4) {
                    if(xhr.status>=200&&xhr.status<=300) {
                        // box.innerHTML=xhr.response;
                        // 手动数据转化
                        // let str = JSON.parse(xhr.response)
                        // console.log(str);  

                        // 自动数据转化
                        // xhr.response.name 这里已经说明 转化成对象的类型
                        box.innerHTML=xhr.response.name;
                    }
                }
            }
        }
    </script>
</body>
</html>

服务器

// 引入express框架
const express=require("express");
// 创建应用对象
const app=express();
// 创建路由
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server',(request,response)=>{
    // 设置响应头  用来设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应体
    response.send("HELLOajax");
})

// 接受任意类型的请求
// 接受自定义请求头之结合搜的方法成为了OPTIONS
app.all('/server',(request,response)=>{
    // 设置响应头  用来设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 接受自定义的头
    response.setHeader('Access-Control-Allow-Headers','*');
    // 设置响应体
    response.send("HELLO AJAX");
})
app.get('/json-server',(request,response)=>{
    // 设置响应头  用来设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 接受自定义的头
    response.setHeader('Access-Control-Allow-Headers','*');
    // 响应一个数据
    const data = {
        name:'sunpengda'
    }
    // 将对象数据转换成字符串
    const str = JSON.stringify(data);
    // 设置响应体
    response.send(data);
})
// 监听端口启动
app.listen(7000,()=>{
    console.log("服务器启动成功");
})
  1. 前后端信息传输的时候,使用字符串的格式进行传输。json对象转换成字符串(JSON.stringify)和字符串转换成JSON对象的形式(JSON.parse)。
  2. 转换分为手动数据转换和自动转换。转换时注意json的大小写

解决服务器启动问题

问题:更改一次js文件就要重启一次服务器

方案:当服务器有变动的时候,自动重启服务器

方法:在终端输入:npm install -g nodemon 之后在js所在的文件夹下面输入:npx nodemon

IE缓存问题的解决

解决方法如下:

            // Data.now() 是一个时间戳 每一时刻的数值都不一样,这样服务器会认为这是两个不一样的请求,这样就可以重新发送新的请求,为不是本地缓存
            xhr.open('GET','http://localhost:7000/ie?t='+Data.now());

请求超时和网络异常

html

<!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>
        .box {
            width: 100px;
            height: 50px;
            border: solid 1px green;
        }
    </style>
</head>
<body>
    <button>点击</button>
    <div class="box"></div>
    <script>
        // IE浏览器会对Ajax请求结果进行缓存,导致下一次请求的结果是,Ajax上一次缓存的结果。而不是最新的数据
        const btn = document.querySelector('button');
        const box = document.querySelector('.box');
        btn.addEventListener('click',function(){
            const xhr = new XMLHttpRequest();
            // 超时 设置 2s
            xhr.timeout=2000;
            // 超时问题
            xhr.ontimeout=function(){
                alert('网络异常,请稍后重试')
            }
            // 网络异常问题
            xhr.onerror=function(){
                alert("你的网络似乎出现一些问题");
            }
            xhr.open('GET','http://localhost:7000/delay');
            xhr.send();
            xhr.onreadystatechange=function(){
                if(xhr.readyState===4) {
                    if(xhr.status>=200&&xhr.status<=300) {
                      box.innerHTML=xhr.response;
                    }
                }
            }
        })
    </script>
</body>
</html>

服务器

//在前面的基础上再次添加路由
app.get('/delay',(request,response)=>{
    // 设置响应头,允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应体
    setTimeout(()=>{
        response.send('HELLO delay');
    },3000)
})

取消请求

html

<!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>
</head>
<body>
    <button>点击发送</button>
    <button>点击取消</button>
    <script>
        const btns = document.querySelectorAll('button');
        // const x =null;  不能使用 若使用const,那么在第二个函数中x就会发生变更
        // const和let同为块级作用域,但const声明同时必须初始化且不能修改
        let x = null;
        btns[0].onclick=function(){
            x = new XMLHttpRequest();
            x.open('get','http://localhost:7000/delay');
            x.send();
        }
        // abort 是属于x对象的,但是由于作用于的问题需要对x进行处理
        btns[1].onclick=function(){
            x.abort();
        }
    </script>
</body>
</html>

服务器不做更改,使用上一个案例的延迟路由。

abort(),是用来取消(正在发送)请求的。已经发送的请求,使用abort取消不了。(这就是为什么使用延迟的路由)

请求重复问题

html

<!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>
</head>
<body>
    <button>点击发送</button>
    <button>点击取消</button>
    <script>
        const btns = document.querySelectorAll('button');
        let x = null;
        // 请求是否正在发送
        let Sending = false;
        btns[0].onclick=function(){
            if(Sending){x.abort()}; //如果请求正在发送,就取消请求
            x = new XMLHttpRequest();
            // 请求正在发送
            Sending = true;
            x.open('get','http://localhost:7000/delay');
            x.send();
            x.onreadystatechange=function(){
                if(x.readyState===4) {
                    Sending=false;
                }
            }
        }
        btns[1].onclick=function(){
            x.abort();
        }
    </script>
</body>
</html>

服务器还是使用延迟案例的路由。

注意:这里Sending不是节流阀,Sending是将前面的操作取消,节流阀是将后面的操作取消。