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("服务器启动成功");
})
- 前后端信息传输的时候,使用字符串的格式进行传输。json对象转换成字符串(JSON.stringify)和字符串转换成JSON对象的形式(JSON.parse)。
- 转换分为手动数据转换和自动转换。转换时注意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是将前面的操作取消,节流阀是将后面的操作取消。