请求超时与网络异常问题

超时

html:

  1. <script>
  2. const btn = document.querySelector("button");
  3. const result = document.querySelector("#result");
  4. btn.addEventListener('click', function(){
  5. const xhr = new XMLHttpRequest();
  6. //增加超时设置:请求超过两秒就取消
  7. xhr.timeout = 2000;
  8. xhr.open("GET","http://127.0.0.1:8000/delay");
  9. xhr.send();
  10. xhr.onreadystatechange = function() {
  11. if(xhr.readyState === 4){
  12. if(xhr.status >=200 && xhr.status < 300){
  13. result.innerHTML = xhr.response;
  14. }
  15. }
  16. }
  17. })
  18. </script>

server.js:add

  1. //延时响应
  2. app.get('/delay',(request, response)=>{
  3. //设置响应头 设置允许跨域
  4. response.setHeader("Access-Control-Allow-Origin","*");
  5. //设置一个延时响应来测试
  6. setTimeout(() => {
  7. //设置响应体
  8. response.send("Hello delay-issue");
  9. }, 3000);
  10. })

image.png
超时就会取消
可以再添加一个超时时的回调函数

  1. //增加超时设置:请求超过两秒就取消
  2. xhr.timeout = 2000;
  3. //超时回调
  4. xhr.ontimeout=()=>{
  5. alert("网络超时,请稍后重试")
  6. }

image.png
实际运用中,我们会选择更加友好的方式,如展现一个div来充当遮罩层以提高用户的体验。

网络异常

添加网络异常回调函数

  1. //超时回调
  2. xhr.ontimeout=()=>{
  3. alert("网络超时,请稍后重试")
  4. }
  5. //网络异常回调函数
  6. xhr.onerror = ()=>{
  7. alert("网络似乎出现了一些问题");
  8. }

image.png
可以通过chrome的工具来测试—设置为offline断网
效果:
image.png

取消请求

发送请求后,结果返回之前,可以通过代码手动取消代码
要用到abort方法
html

  1. <body>
  2. <button>点击发送请求</button>
  3. <button>点击取消请求</button>
  4. <script>
  5. const btns = document.querySelectorAll("button");
  6. let xhr = null;//细节
  7. btns[0].onclick = function(){
  8. xhr =new XMLHttpRequest();
  9. xhr.open("GET","http://127.0.0.1:8000/delay");
  10. xhr.send();
  11. }
  12. //abort方法
  13. btns[1].onclick = function(){
  14. xhr.abort();//如果xhr不像前面那样定义在外面,这里是访问不到的。
  15. }
  16. </script>
  17. </body>

第一个是没取消,三秒后送达;第二个取消。
image.png

重复发送请求问题

有时出了一些问题,按钮点击后没有反应,用户就可能重复点击按钮,实际上是有反应的,用户会重复地发请求,这时服务器就会重复的试图返回相同的响应,这样就会产生问题。
我们可以判断发送请求是否相同,如果相同,就把前面未响应的请求取消掉。减少服务器的压力。
image.png

  1. <body>
  2. <button>点击发送请求</button>
  3. <script>
  4. const btns = document.querySelectorAll("button");
  5. let xhr = null;//细节
  6. //设置一个标识变量:是否正在发送AJAX请求
  7. let isSending = false;
  8. btns[0].onclick = function(){
  9. //判断表示变量
  10. if(isSending){
  11. xhr.abort();//正在发送就把原来的取消,创建新的请求。
  12. }
  13. xhr =new XMLHttpRequest();
  14. //修改标识
  15. isSending = true;
  16. xhr.open("GET","http://127.0.0.1:8000/delay");
  17. xhr.send();
  18. xhr.onreadystatechange = function(){
  19. if(xhr.readyState === 4){//发送完毕
  20. //修改标识
  21. isSending = false;
  22. }
  23. }
  24. }
  25. </script>
  26. </body>

image.png
前面的都会被取消掉—->减轻服务器的压力。