前言
本文主要记录博主遇到的JavaScrprt的补充知识。
Ajax
参考:3小时Ajax入门到精通 CSDN
AJAX 简介
异步的 JS 和 XML(AsynchronousJavaScript And XML),浏览通过 Ajax 向服务器发送异步请求,可以无刷新获取数据。
- 优点:无需刷新页面与服务器端进行通信、允许你根据用户事件来更新部分页面内容
- 缺点:没有浏览历史不能回退、存在跨域问题、SEO 不友好
XML 简介
可扩展标记语言,和 HTML 类似,但 XML 中没有预定义标签,用来表示一些数据
1 2 3 4 5 6 7 8
| <student> <name>张三</name> <age>18</age> <gender>男</gender> </student>
{"name":"孙悟空","age":18,"gender":"男"}
|
请求报文
- 请求行:请求类型(method–get、post) 请求路径(url)、HTTP版本协议(HTTP1.1、HTTP2.0)
- 请求头: 格式(key:value),如:Content-type: application/x-www-form-urlencoded
- 请求空行:必须要有
- 请求体:get请求体为空、post可有可无
响应报文
- 响应行:HTTP版本协议(HTTP1.1、HTTP2.0)、响应状态码(200)、响应状态字符串(ok)
- 响应头: 格式(key:value),如:Content-type: text/html;charset=utf-8
- 响应空行:必须要有
- 响应体:响应主要内容
原生 Ajax 使用
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
const xhr = new XMLHttpRequest();
xhr.open('Get', 'http://localhost:3333')
xhr.send();
xhr.onreadystatechange = () => { if (xhr.readyState === 4 && xhr.status == 200) { console.log(xhr.response) console.log(xhr.status) console.log(xhr.statusText) console.log(xhr.getResponseHeader('Content-type')) console.log(xhr.getAllResponseHeaders) } }
xhr.open('Get', 'http://localhost:3333?a=100&b=200')
xhr.send('a=100&b=200')
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded') xhr.setRequestHeader('token','xxx')
JSON.parse(xhr.response)
xhr.responseType = 'json'
xhr.open('Get', 'http://localhost:3333?t='+Date.now)
xhr.timeout = 2000;
xhr.ontimeout = function(){ alert('网络超时,请稍后重试') }
xhr.onerror = function(){ alert('网络异常,请稍后重试') }
xhr.abort()
|
JQuery Ajax 使用
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 33 34
|
$.get('http://localhost:8000/jquery-server', {}, function(data){ console.log(data) }, 'json')
$.post('http://localhost:8000/jquery-server', {a:100, b:200}, function(data){ console.log(data) }, 'json')
$.ajax({ type: 'GET', url: 'http://localhost:8000/jquery-server', data: {}, dataType: 'json', timeout: 3000, headers: { token: 'xxx' }, success: function(res) { console.log(res) }, error: function(e) { console.log(e) }, complete: function(data) { console.log(data) } })
|
axios 使用
文档:axios
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
| axios.get('http://localhost:8000/axios-server', { params: { id: 1 }, headers:{ name:'xxx' } }).then()
axios.post('http://localhost:8000/axios-server', { a: 10 }, { params: { id: 1 }, headers:{ name:'xxx' } }).then()
axios({...}).then()
|
fetch 语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| fetch('http://localhost:8000/fetch-server',{ method:'POST', headers:{ name:'hanser' }, body: 'name=admin&pd=admin' }).then(Response=>{ console.log(Response) return Response.text() }).then(Response=>{ console.log(Response) })
|
jsonp 的使用
JSONP(JSON with Padding),是一个非官方的跨域解决方案,只支持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
|
function handle(data) { console.log(data) }
const script = document.createElement('script')
script.src = 'http://localhost:8000/check-username'
document.body.appendChild(script)
app.all("/articles", (req, res) => { let data = JSON.stringify({name:'xxx'}) res.send(`handle(${data})`); });
$.getJSON('xxx?callback=?', function(data) { console.log(data) })
|
补充跨域CORS:就是服务端设置请求头,来允许哪些可以访问资源,还有是否支持自定义请求头、请求响应方法等。
资料:CORS
Promise 补充
参考:尚硅谷Web前端Promise教程从入门到精通
Promise api
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| let p1 = Promise.resolve(521);
let p2 = Promise.resolve(new Promise((resolve, reject) => { reject('Error'); }));
p2.catch(reason => { console.log(reason); })
let p = Promise.reject(521); let p2 = Promise.reject('iloveyou'); let p3 = Promise.reject(new Promise((resolve, reject) => { resolve('OK'); }));
let p1 = new Promise((resolve, reject) => { resolve('OK'); }) let p2 = Promise.resolve('Success'); let p3 = Promise.resolve('Oh Yeah');
const result = Promise.all([p1, p2, p3]); console.log(result);
const pRace = Promise.race([p1, p2, p3])
let p1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('OK'); }, 1000); }) let p2 = Promise.resolve('Success'); let p3 = Promise.resolve('Oh Yeah');
const result = Promise.race([p1, p2, p3]);
console.log(result);
|
Promise 的几个问题
1.如何改变 promise 的状态?
1 2 3 4 5 6 7 8 9 10
| const p = new Promise((resolve, reject) => { throw new Error('出错了') }) p.then( value => {}, reason => {console.log('reason',reason)} )
|
2.一个 promise 指定多个成功/失败回调函数,都会调用吗?
当 promise 改变为对应状态时都会调用
3.改变 Promise 状态和指定回调函数谁先谁后?
- 都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
- 如何先改状态再指定回调?
在执行器中直接调用 resolve()/reject()
延迟更长时间才调用 then()
如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据
如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据
4.Promise then方法的返回结果特点
如果返回的是另一个新promise,此promise的结果就会成为新promise的结果
如果返回的是非promise的任意值,新promise变为resolved,value为返回的值
如果抛出异常,新promise变为rejected,reason为抛出的异常
5.异常穿透
当使用 Promise 的 then 链式调用时, 可以在最后指定失败的回调
前面任何操作出了异常, 都会传到最后失败的回调中处理
6.中断 promise 链
当使用promise的then链式调用时,在中间中断,不再调用后面的回调函数,办法:在回调函数中返回一个pending状态的promise对象
补充 axios.all 使用
1 2 3 4 5 6 7 8 9 10 11 12
| function getUserAccount() { return axios.get('/user/12345'); } function getUserPermissions() { return axios.get('/user/12345/permissions'); } axios.all([getUserAccount(), getUserPermissions()]) .then( axios.spread(function (acct, perms) { }));
|