目標
javascript
/* 1. 說出什麼是先後端交互模式 2. 說出Promise的相關概念和用法 3. 使用fetch進行接口調用 4. 使用axios進行接口調用 5. 使用asynnc/await方式調用接口 6. 基於後臺接口實現案例 */
/* 原生ajax 基於jQuery的ajax fetch axios */
/* 格式: schema://host:port/path?query#fragment 1. schema: 協議. 例如http,https,ftp等 2. host: 域名或者IP地址 3. port: 端口,http默認端口80,能夠省略 4. path: 路徑,例如/abc/a/b/c 5. query: 查詢參數uname=list&age=12 6. fragment: 錨點(哈希Hash),用於定位頁面某個位置 */
/* HTTP請求方式 1. GET 查詢 2. POST 添加 3. PUT 修改 4. DELETE 刪除 */
異步調用分析
html
/* 1. 定時任務 2. Ajax 3. 事件函數 */
屢次異步調用的依賴分析
vue
/* 屢次異步調用的結果順序不肯定 異步調用結果若是存在依賴須要嵌套 */
Example(傳統ajax)
java
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: {}, methods: {} }) </script> </body> </html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div>先後端交互</div> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript"> /* 先後端交互,異步編程與Promise概述 */ var ret = '---' $.ajax({ url: 'http://localhost:3000/data', success: function (data) { ret = data console.log(ret) } }); console.log(ret) </script> </body> </html>
Promise是異步編程的一種解決方案,從語法上講,Promise是一個對象,從他能夠獲取異步操做的信息.node
/* 使用Promise主要有如下好處: 能夠避免多層異步調用嵌套問題(回調地獄) Promise對象提供了簡介的API,使得控制異步操做更加容易 */
/* 基本用法 實例化Promise對象,構造函數中傳遞函數,該函數用於處理異步任務. resolv和reject兩個參數用於處理成功和失敗兩種狀況,並經過p.then獲取處理結果. */ var p = new Promise(function(resolve,reject){ // 成功時調用 resolve() // 失敗時調用 reject() p.then(function(ret){ // 從resolve獲得正常結果 },function(ret){ // 從reject獲得錯誤信息 }); });
Example1
jquery
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: {}, methods: {} }) </script> </body> </html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div>先後端交互</div> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript"> /* Promise基本使用 */ var p = new Promise(function (resolve, reject) { // 這裏用於實現異步任務 setTimeout(function () { var flag = false; if (flag) { // 正常狀況 resolve('hello'); } else { // 異常狀況 reject('500'); } }, 100); }); p.then(function (data) { console.log(data) }, function (info) { console.log(info) }) </script> </body> </html>
function queryData(){ return new Promise(function(resolve,reject){ var xhr - new XMLHttpRequest(); xhr.cnreadystatechange = function(){ if(xhr.readyState != 4) return; if(xhr.status == 200){ resolve(xhr.responseText) }else{ reject('出錯了'); } } xhr.open('get','/data'); xhr.send(null); }) }
處理屢次Ajax請求
ios
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: {}, methods: {} }) </script> </body> </html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div>先後端交互</div> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript"> /* 基於Promise發送Ajax請求 */ function queryData(url) { var p = new Promise(function (resolve, reject) { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState != 4) return; if (xhr.readyState == 4 && xhr.status == 200) { // 處理正常狀況 resolve(xhr.responseText); } else { // 處理異常狀況 reject('服務器錯誤'); } }; xhr.open('get', url); xhr.send(null); }); return p; } // queryData('http://localhost:3000/data') // .then(function(data){ // console.log(data) // },function(info){ // console.log(info) // }); // 發送多個Ajax請求而且保證順序 queryData('http://localhost:3000/data') .then(function (data) { console.log(data) return queryData('http://localhost:3000/data1'); }) .then(function (data) { console.log(data); return queryData('http://localhost:3000/data2'); }) .then(function (data) { console.log(data) }); </script> </body> </html>
/* 1. 返回Promise實例對象 返回的該實例對象會調用下一個then 2. 返回普通值 返回的普通值會直接傳遞給下一個then,經過then參數中函數的參數接受該值 */
Example
ajax
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> /* then參數中的函數返回值 */ function queryData(url) { return new Promise(function(resolve, reject){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState != 4) return; if(xhr.readyState == 4 && xhr.status == 200) { // 處理正常的狀況 resolve(xhr.responseText); }else{ // 處理異常狀況 reject('服務器錯誤'); } }; xhr.open('get', url); xhr.send(null); }); } queryData('http://localhost:3000/data') .then(function(data){ return queryData('http://localhost:3000/data1'); }) .then(function(data){ return new Promise(function(resolve, reject){ setTimeout(function(){ resolve(123); },1000) }); }) .then(function(data){ return 'hello'; }) .then(function(data){ console.log(data) }) </script> </body> </html>
/* 實例方法 p.then() 獲得異步任務的正確結果 p.catch() 獲取異常信息 p.finally() 成功與否都會執行(尚且不是正式標準) queryData() .then(function(data){ console.log(data); }) .catch(function(data){ console.log(data); }) .finally(function(){ console.log('finished'); }); */
Example1
chrome
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> /* Promise經常使用API-實例方法 */ // console.dir(Promise); function foo() { return new Promise(function(resolve, reject){ setTimeout(function(){ // resolve(123); reject('error'); }, 100); }) } // foo() // .then(function(data){ // console.log(data) // }) // .catch(function(data){ // console.log(data) // }) // .finally(function(){ // console.log('finished') // }); // -------------------------- // 兩種寫法是等效的 foo() .then(function(data){ console.log(data) },function(data){ console.log(data) }) .finally(function(){ console.log('finished') }); </script> </body> </html>
對象方法
npm
/* Promise.all() 併發處理多個異步任務,全部任務都執行成功才能獲得結果 Promise.race() 併發處理多個異步任務,只要有一個任務完成就能獲得結果 */ Promise.all([p1,p2,p3]).then((result) =>{ console.log(result) }) Promise.race([p1,p2,p3]).then((result) =>{ console.log(result) })
Example
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> /* Promise經常使用API-對象方法 */ // console.dir(Promise) function queryData(url) { return new Promise(function (resolve, reject) { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState != 4) return; if (xhr.readyState == 4 && xhr.status == 200) { // 處理正常的狀況 resolve(xhr.responseText); } else { // 處理異常狀況 reject('服務器錯誤'); } }; xhr.open('get', url); xhr.send(null); }); } var p1 = queryData('http://localhost:3000/a1'); var p2 = queryData('http://localhost:3000/a2'); var p3 = queryData('http://localhost:3000/a3'); // Promise.all([p1,p2,p3]).then(function(result){ // console.log(result) // }) Promise.race([p1, p2, p3]).then(function (result) { console.log(result) }) </script> </body> </html>
fetch
XMLHttpRequest是一個設計粗糙的API, 配置和調用方式很是混亂,並且基於事件的異步模型寫起來不友好,兼容性很差.
/* 更加簡單的數據獲取方式,功能更強大,更靈活,能夠看作是xhr升級版 基於Promise實現 */
Example
fetch('/abc').then(data=>{ return data.text(); }).then(ret=>{ // 注意這裏獲得的纔是最終的數據 console.log(ret); })
Example1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: {}, methods: {} }) </script> </body> </html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> /* Fetch API基本用法 */ fetch('http://localhost:3000/fdata').then(function (data) { // text() 方法屬於fetchAPI的一部分,他返回一個Promise實例對象,用於獲取後臺返回數據 return data.text(); }).then(function (data) { // 這裏獲得的纔是最終的數據 console.log(data); }) </script> </body> </html>
Example2
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Examples</title> <meta name="description" content=""> <meta name="keywords" content=""> <link href="" rel="stylesheet"> <script type="text/javascript" src="lib/vue.js"></script> </head> <body> <div id="box"> <button @click="handleClick()">獲取影片信息</button> <ul> <li v-for="data in datalist"> <h3>{{ data.name }}</h3> <img :src="data.poster"> </li> </ul> </div> <script> new Vue({ el: "#box", data: { datalist: [] }, methods: { handleClick() { fetch("./json/test.json").then(res => res.json()).then(res => { console.log(res.data.films) this.datalist = res.data.films }) } } }) </script> <!-- new Vue({ el: "#box", data:{ datalist:["111","222","333"] } }) --> </body> </html>
經常使用配置選項
/* method(String): HTTP請求方法,默認爲GET(GET,POST,PUT,DELETE) body(String): HTTP的請求參數 headers(Object) HTTP的請求頭,默認爲{} */
GET請求方式的參數傳遞
fetch('/abc?id=123').then(data=>{ return data.text(); }).then(ret=>{ // 注意這裏獲得的纔是最終的數據 console.log(ret) }) fetch('/abc/123',{ method 'get' }).then(data=>{ return data.text(); }).then(ret=>{ // 注意這裏獲得的纔是最終的數據 console.log(ret); });
Example1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: {}, methods: {} }) </script> </body> </html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> /* Fetch API: 調用接口傳遞參數 */ // fetch('http://localhost:3000/books?id=123',{ // method: 'get' // }) // .then(function (data) { // return data.text(); // }).then(function (data) { // console.log(data) // }); fetch('http://localhost:3000/books/123',{ method: 'get' }) .then(function (data) { return data.text(); }).then(function (data) { console.log(data) }); </script> </body> </html>
POST請求方式參數傳遞
fetch('/books',{ method: 'post', body: 'uname=list&pwd=123', headers: { 'Content-Type': 'application/x-www-form-urlencoded', } }).then(data=>{ return data.text(); }).then(ret=>{ console.log(ret); })
響應數據格式
/* text(): 將返回體處理成字符串類型 json(): 返回結果和JSON.parse(responseText)同樣 */ fetch('/abc' then(data=>{ // return data.text(); return data.json(); }),then(ret=>{ console.log(ret); });
/* axios是一個基於Promise用於瀏覽器和node.js的HTTP客戶端. 具備如下特徵: 支持瀏覽器和node.js 支持promise 能攔截請求和響應 自動轉換JSON數據 */
axios.get('/adata') .then(ret=>{ // data屬性名稱是固定的,用於獲取後臺響應的數據 console.log(ret.data) })
Example1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script type="text/javascript"> axios.get('http://localhost:3000/adata').then(function (ret) { // 注意data屬性是固定的用法,用於獲取後臺的實際數據 console.log(ret.data) }) </script> </body> </html>
GET傳遞參數
/* 經過URL傳遞參數 經過params選項傳遞參數 */
Exmaple2
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script type="text/javascript"> // axios.get('http://localhost:3000/axios?id=1234').then(function (ret) { // // 注意data屬性是固定的用法,用於獲取後臺的實際數據 // console.log(ret.data) // }) axios.get('http://localhost:3000/adata', { params: { id: 700 } }) .then(function (ret) { console.log(ret.data) }) // axios.get('http://localhost:3000/axios/1234').then(function (ret) { // // 注意data屬性是固定的用法,用於獲取後臺的實際數據 // console.log(ret.data) // }) </script> </body> </html>
POST傳遞參數
經過選項傳遞參數(默認傳遞的是json格式的數據)
Example1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script type="text/javascript"> axios.post('http://localhost:3000/axios', { uname: 'lisi', pwd: 123 }).then(function(ret){ console.log(ret.data) }) </script> </body> </html>
經過URLSearchParams傳遞參數(application/x-www-form-urlencoded)
Example2
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script type="text/javascript"> var params = new URLSearchParams(); params.append('uname','youmen'); params.append('pwd','123'); axios.post('http://localhost:3000/axios',params).then(function(ret) { console.log(ret.data) }) </script> </body> </html>
/* data: 實際響應回來的數據 header: 響應頭信息 status: 響應狀態碼 statusText: 響應狀態信息 */
Example1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script type="text/javascript"> /* axios 響應式結果與全局配置 */ axios.get('http://localhost:3000/axios-json').then(function(ret) { console.log(ret.data) }) </script> </body> </html>
/* axios.default.timeout=3000; //超時時間 axios.defaults.baseURL='http://localhost:3000/app'; // 默認地址 axios.defaults.headers['mytoken'] = 'asadfjksdfjkdsaf' // 設置請求頭 */
Example1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script type="text/javascript"> /* axios 響應式結果與全局配置 */ axios.defaults.baseURI = 'http://localhost:3000/'; // 設置頭信息 axios.defaults.headers['mytoken'] = 'hello'; axios.get('axios-json').then(function(ret) { console.log(ret) }) </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Examples</title> <meta name="description" content=""> <meta name="keywords" content=""> <link href="" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script type="text/javascript" src="lib/vue.js"></script> </head> <body> <div id="box"> <button @click="handleClick()">正在熱映</button> <ul> <li v-for="data in datalist"> <h1>{{ data.name }}</h1> <img :src="data.poster"> </li> </ul> </div> <script> new Vue({ el: "#box", data: { datalist: [] }, methods: { handleClick() { axios.get("./json/test.json").then(res => { // axios 自歐東包裝data屬性 res.data console.log(res.data.data.films) this.datalist = res.data.data.films }).catch(err => { console.log(err); }) } } }) </script> </body> </html>