异步js,axios
1. 原生ajax
1.1. ajax简介
全称:Asynchronous JavaScript And XML (异步JavaScript和XML)
在网页中利用XMLHttpRequest对象和服务器进行数据交互的方式就是ajax
通过ajax可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据
ajax不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式
1.2. XML简介
Extensible Makeup Language,可拓展标记语言
被用来传输和存储数据
和html不同,HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示数据
1 2 3 4 5
   | <student>   <name>name</name>   <age>18</age>   <gender>female</gender> </student>
   | 
 
现在已经被json取代
1 2 3 4 5
   | {   "name":'name',   "age":18,   "gender":"female" }
  | 
 
2. HTTP协议
Hypertext transport protocol 超文本传输协议
协议规定了浏览器和万维网服务器之间互相通信的规则
2.1. 请求报文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | # 请求行 请求方式 url HTTP/1.1
  # 请求头 access-control-allow-origin: * cache-control: max-age=31536000 content-encoding: gzip content-md5: NZucY8s7pDOEspleVpmmPw== content-type: application/x-javascript server: AliyunOSS
  # 空行
  # 请求体 post方式下存在提交表单:name=name&&password=123
   | 
 
2.2. 响应报文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | # 响应行 HTTP/1.1 200 OK
  # 响应头 access-control-allow-origin: * cache-control: max-age=31536000 content-encoding: gzip content-md5: NZucY8s7pDOEspleVpmmPw== content-type: application/x-javascript server: AliyunOSS
  # 空行
  # 响应体 <html> 	<head></head> 	<body></body> </html>
   | 
 
3. 基本操作
3.1. 核心对象
XMLHttpRequest,AJAX 的所有操作都是通过该对象进行的。
3.2. AJAX 请求状态
xhr.readyState 可以用来查看请求当前的状态
 https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readyState
0: 表示 XMLHttpRequest 实例已经生成,但是 open()方法还没有被调用
1: 表示 send()方法还没有被调用,仍然可以使用 setRequestHeader(),设定 HTTP请求的头信息
2: 表示 send()方法已经执行,并且头信息和状态码已经收到
3: 表示正在接收服务器传来的 body 部分的数据
4: 表示服务器数据已经完全接收,或者本次接收已经失败了
3.3. get
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
   |  const xhr = new XMLHttpRequest();
 
  xhr.open("get","http://127.0.0.1:3700/show/all");
 
  xhr.send();
 
 
 
 
 
 
 
  xhr.onreadystatechange = function(e){      if(xhr.readyState == 4){               console.log(xhr.status);          console.log(xhr.statusText);                    console.log(xhr.getAllResponseHeaders());          console.log(xhr.response);   } }
 
  | 
 
3.4. post
1 2 3 4 5 6 7 8 9 10
   |  const xhr = new XMLHttpRequest();
 
  xhr.open("post","http://127.0.0.1:3700/show/all");
 
 
 
 
 
 
  | 
 
3.5. 设置请求头
1
   | xhr.setRequestHeader("Content-Type","application/xxx-form-urlencoded");
  | 
 
需要允许自定义请求头
1
   | response.setHeader("Access-Control-Allow-Header","*");
  | 
 
此时会预先发送OPTIONS 请求
1 2 3 4 5 6 7 8
   | app.all("/show",(request,response)=>{   	   	response.setHeader("Access-Control-Allow-Origin","*");   	   	response.setHeader("Access-Control-Allow-Header","*");          response.send("Hello Ajax"); });
  | 
 
4. 响应JSON数据
4.1. 方法一:JSON.parse()
1 2 3 4 5 6 7 8 9 10
   |  const data={   name: 'uname' } let str = JSON.stringify(data);
 
 
  let data = JSON.parse(xhr.reponse); document.getElementById("div").innerHTML = data.name;
 
  | 
 
4.2. 方法二:xhr.responseText
1 2 3
   |   xhr.responseText="json"; let data = xhr.reponse.name;
 
  | 
 
5. IE缓存问题
IE对于同一个路由访问请求到的数据进行缓存,再次请求得到的是缓存数据
解决:时间戳
1
   | xhr.open("get","http://127.0.0.1/show/all?time="+Date.now());
  | 
 
6. 请求超时与异常处理
1 2 3 4 5 6 7 8 9 10 11 12
   |  xhr.timeout=2000;
 
  xhr.ontimeout = function(){   alert("超时"); }
 
  xhr.onerror = function(){   alert("网络异常"); }
 
  | 
 
7. 取消请求
8. 重复访问路由
设置互斥锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   | let xhr = null; let isSending = false;
  document.querySelectorAll("button")[0].onclick = function(){   	if(isSending){              xhr.abort();     }   	  		     xhr = new XMLHttpRequest();
           xhr.open("get","http://127.0.0.1:3700/show/all");
           xhr.send();
           xhr.onreadystatechange = function(e){
        if(xhr.readyState == 4){         isSending = true;       }     }  }
   | 
 
9. JQuery发送ajax
9.1. get
$.get(url, [data], [callback], [type])
	url:请求的 URL 地址
	data:请求携带的参数
	callback:载入成功时回调函数 
	type:设置返回内容格式,xml, html, script, json, text, _default
1 2 3 4
   |  $.get('http://127.0.0.1:3700/show/all',"basketball=1",function(data){     console.log(data);   });
 
  | 
 
9.2. post
$.post(url, [data], [callback], [type])
	url:请求的 URL 地址 
	data:请求携带的参数
	callback:载入成功时回调函数
	type:设置返回内容格式,xml, html, script, json, text, _default
1 2 3 4
   |  $.post('http://127.0.0.1:3700/show/all',"basketball=1",function(data){     console.log(data);   });
 
  | 
 
9.3. 直接使用ajax
https://jquery.cuishifeng.cn/jQuery.Ajax.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | $.ajax({   url: 'http://127.0.0.1:3700/show/all',      data: "basketball=1",      method: 'get',      dataType: 'json',      success: function(data){     console.log(data);   },   error:function(){
    },      timeout: 200,      headers: {     "Content-Type":"applcation/xxx-form-urlencoded"   }
  })
  | 
 
10. axios
https://github.com/axios/axios
doc:https://axios-http.com/zh/
插件:https://www.bootcdn.cn/
10.1. get
1 2 3 4 5 6 7
   | axios.get("/show/all",{   params: {     basketball: 1   } }).then(function(res){   console.log(res.data); })
  | 
 
10.2. post
axios.post(url[, data[, config]])
1 2 3 4 5 6 7 8 9
   | axios.post("/show/all",{     username: 'uname'   },{    params: {      basketball: 1    }  }).then(function(res){    console.log(res.data);  })
  | 
 
10.3. ajax
1 2 3 4 5 6 7 8 9 10 11 12
   |  axios({    url: "/show/all",    method: 'post',    data: {      username: 'uname'    },    params: {       basketball: 1    }  }).then(function(res){     console.log(res.data); });
  | 
 
11. fetch
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API
1 2 3 4 5 6 7 8 9
   | fetch("http://127.0.0.1:3700/show/all",{   method: 'get' }).then(res=>{         return res.json(); }).then(data=>{   console.log(data); })
  | 
 
12. 同源
同源策略(Same-Origin Policy)最早由 Netscape 公司提出,是浏览器的一种安全策略。
协议,域名,端口号 必须完全相同
12.1. 解决策略一jsonp
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持 get 请求
12.1.1. JSONP 怎么工作的?
在网页有一些标签天生具有跨域能力,比如:img link iframe script。JSONP 就是利用 script 标签的跨域能力来发送请求的。
12.1.2. JSONP 的使用
html中的script标签支持跨域
1 2 3 4 5 6 7
   | app.get("/jsonp",(req,res)=>{     const data = {         username: 'uname'     }     let str = JSON.stringify(data);     res.end(`handle(${str})`); })
  | 
 
html
1 2 3 4 5 6
   | <script> 		function handle(json){       console.log(json);     } </script> <script src="http://127.0.0.1:3700/jsonp"></script>
   | 
 
12.2. JQuery版
1 2 3 4 5 6 7 8
   | app.get("/jsonp",(req,res)=>{     const data = {         username: 'uname'     }     let str = JSON.stringify(data);     let cb = req.query.callback;     res.end(`${cb}(${str})`); })
  | 
 
js
1 2 3
   | $.getJSON("http://127.0.0.1:3700/jsonp?callback=?",function(data){ 	console.log(data); })
  | 
 
最终调用的路由为 http://127.0.0.1:3700/jsonp?callback=jQuery360012005959090789764_1655395933862&_=1655395933864
故返回的方法为
1
   | jQuery360012005959090789764_1655395933862({username: "uname"})
  | 
 
12.3. 解决策略二 CORS
CORS(Cross-Origin Resource Sharing),跨域资源共享。
CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持 get 和 post 请求
跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
12.3.1. CORS 怎么工作的?
CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行
12.3.2. CORS 的使用
1 2 3
   | res.set("Access-Control-Allow-Origin","http://127.0.0.1:3000");
  res.set("Access-Control-Allow-Origin","*");
  |