异步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","*");
|