Nodemon自动重启服务器
我们前面进行的学习,每次修改完服务端代码后,都需要重启一次服务器,才能将新代码运用到服务器中,来回重启会很麻烦,所以我们可用安装nodemon来帮我们解决重启问题。
在安装nodemon之前,需要安装node.js,如果还没有安装,可以看[Ajax使用准备](https://www.yuque.com/u12581613/sr444s/gyxuc5?view=doc_embed)中的安装方法。<br />**_安装nodemon_**
- 在集成终端输入命令:
npm install -g nodemon
- 重新启动服务:使用命令 ->
nodemon 文件名
,但是这样可能会不成功,会有错误信息,如果出现错误,可以使用 ->nodemon.cmd 文件名
- 之后我们再修改服务端代码,nodemon就会帮我们自动刷新服务了。
解决IE缓存问题
什么是IE缓存问题呢?IE浏览器会对Ajax的请求结果去做一个缓存,这样的结果呢,就是等下一次发送Ajax请求时,走的是Ajax的缓存,而不是服务器返回的最新数据。
解决问题的方法很简单,只要在xhr.open中多设置一个参数就好了
...
xhr.open("GET","http://127.0.0.1:8000/ie?t=" + Date.now());
我们添加了一个时间戳参数,由于时间戳是不停变动的,所以每一次请求浏览器都会认为是一次新的请求,包括IE浏览器,这个时候就不会走缓存了。
请求超时与网络异常
我们项目上线之后,很有可能会出现请求超时的情况,我们不能保证服务端会永远及时的响应,这个时候我们可以对Ajax做一个超时的设置,并且在网络异常时也给用户一个提醒。
首先要让我们的服务端延迟响应,这样才能模拟实际应用请求超时的场景,我们可以对服务端代码做出如下修改:
//省略部分代码,原代码可看第一节Ajax使用准备章节中内容
app.get("/delay",(request,response)=>{
response.setHeader("Access-Control-Allow-Origin",'*');
//设置延时器,延时3秒发送响应
setTimeout(()=>{
response.send("延时响应");
},3000);
});
...
那我们怎么在前端代码中进行超时设置呢?只需要给xhr添加timeout参数即可,值是允许超时的毫秒。
//基于上节课<解决IE缓存问题>代码进行修改
...
btn.addEventListener("click",function(){
var xhr = new XMLHttpRequest();
//超时设置2s,这里是需要输入毫秒
xhr.timeout = 2000;
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;
}
}
}
});
...
此时,我们回到浏览器打开抓包工具,就会发现超时两秒后,如果还没有结果回来,就把请求做了一个取消。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12969163/1624525791228-49f68e4e-3ff1-4c6d-97d3-fbd9698b1d74.png#clientId=u051d60ba-4f0d-4&from=paste&height=32&id=u33137567&margin=%5Bobject%20Object%5D&name=image.png&originHeight=64&originWidth=1917&originalType=binary&ratio=2&size=10813&status=done&style=none&taskId=u0a874021-b845-4c99-908b-9b6ae749435&width=958.5)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12969163/1624525731989-d1a11474-e8f4-46e4-af23-01654eb205d9.png#clientId=u051d60ba-4f0d-4&from=paste&height=16&id=uab19c003&margin=%5Bobject%20Object%5D&name=image.png&originHeight=31&originWidth=1918&originalType=binary&ratio=2&size=6048&status=done&style=stroke&taskId=u3d1d9315-47ab-44dd-87a6-49f731643e3&width=959)<br />我们还可以为超时添加一个回调,用于提示用户。
...
xhr.timeout = 2000;
xhr.ontimeout = function(){
alert("请求超时,请稍后重试!!!");
}
...
我们同时还可以设置一个网络异常的回调,提示用户网络出现了问题。
xhr.timeout = 2000;
//网络异常回调
xhr.onerror = function(){
alert("你的网络似乎出了一点问题!!");
}
为了演示,我们需要在浏览器的抓包工具中,设置"断网",这样才能出现提示。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12969163/1624526274771-fd87c094-cc5d-4996-b8ec-2ba35e943cfb.png#clientId=u051d60ba-4f0d-4&from=paste&height=153&id=ub75fcb52&margin=%5Bobject%20Object%5D&name=image.png&originHeight=306&originWidth=1916&originalType=binary&ratio=2&size=54319&status=done&style=none&taskId=ucae66745-a064-4313-9950-eabc6da2971&width=958)<br />设置"断网"之后,我们点击按钮发送请求,就会出现提示。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12969163/1624526318928-620408a8-dda9-4809-8ae8-67978c0a0eb5.png#clientId=u051d60ba-4f0d-4&from=paste&height=100&id=u7af6c8a1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=199&originWidth=1920&originalType=binary&ratio=2&size=17038&status=done&style=none&taskId=u2a73634d-94ab-4006-8950-a143b026974&width=960)
取消请求
刚才解决的是特殊情况下取消请求的方式,本节讲的是手动取消请求。
我们简单设置两个按钮,一个用于发送请求,一个用于取消请求,取消请求的方法可以绑定xhr的abort()方法取消。
...
<body>
<button>发送请求</button>
<button>取消请求</button>
<script>
const btn = document.querySelectorAll("button");
//这里需要把xhr设置为全局变量,不同的函数才都可以调用
let xhr = null;
btn[0].onclick = function(){
xhr = new XMLHttpRequest();
xhr.open("GET","http://127.0.0.1:8000/delay");
xhr.send();
//我们不需要返回结果
}
btn[1].onclick = function(){
xhr.abort();
}
</script>
</body>
...
点击第一个按钮时
点击第二个按钮时
解决用户重复发送请求
在前面的课程中,我们每点击一次按钮就会发送一次请求,当我们频繁点击按钮的时候,就会频繁的发送请求,这时候服务器的压力就会很大,它会接收到非常多的相同请求。
所以我们可以判断用户点击一个按钮后,之前有没有相同请求,如果之前有,那么就把之前的请求取消掉,然后发送一个新的。
...
<body>
<button>发送请求</button>
<script>
const btn = document.querySelector("button");
let xhr = null;
//标识变量
let isSending = false; //true表示正在发送请求,false表示没有发送
btn.onclick = function(){
if (isSending) xhr.abort(); //如果正在发送,则取消请求,重新发送请求
xhr = new XMLHttpRequest();
//修改标识变量的值
isSending = true;
xhr.open("GET","http://127.0.0.1:8000/delay");
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
//修改标识变量
isSending = false;
//需要在状态码之前加,因为有可能本次是失败的请求
}
}
}
</script>
</body>
...
这样我们就通过isSending这个变量,判断出了当前是否处于发送状态,当我们多次点击按钮时,就会停止发送上一次的请求,再次发送新的请求。