1. 程式人生 > 實用技巧 >03 Vue前後端互動

03 Vue前後端互動

1.前後端互動模式

1.1 介面呼叫方式

列舉

  • 原生ajax

  • 基於jq的ajax

  • fetch

  • axios

1.2 URL地址格式

1.傳統形式的URL

  • 格式: scheme://host:port/path?query#fragment

  • 協議://域名:埠/路徑?引數#錨點(雜湊Hash)

2.Restful形式的URL

HTTP請求方式

GET 查詢

POST 新增

PUT 修改

DELETE 刪除

符合規則的URL地址

http://www.hello.com/books/123

2.Promise的相關概念和用法

2.1 非同步呼叫

  • 非同步效果分析

    • 1.定時任務

    • 2.Ajax

    • 3.事件函式

  • 多次非同步呼叫的依賴分析

    • 多次非同步呼叫的結果順序不確定

    • 非同步呼叫的結果如果存在依賴需要巢狀

2.2 Promise概述

Promise 是非同步程式設計的一種解決方案,從語法上講,Promise是一個物件,從它可以獲取非同步操作的訊息.

  • 避免多層非同步呼叫巢狀問題(回撥地獄)

  • promise物件提供簡潔的API,使得控制非同步操作更加容易

2.3 Promise 基本用法

  • 例項化Promise物件,建構函式中傳遞函式,該函式中用於處理非同步任務

  • resolve和reject 兩個引數用於處理成功和失敗的情況,通過p.then獲取處理結果

1.如何定義一個promise例項

我們使用new來構建一個Promise Promise的建構函式接收一個引數,是函式,並且傳入兩個引數: resolve,reject, 分別表示非同步操作執行成功後的回撥函式和非同步操作執行失敗後的回撥函式 Promise例項生成以後,可以用then方法指定resolved狀態和reject狀態的回撥函式

演示

<body>
    <script>
        var p = new Promise(function(resolve, reject) {
            // 用於實現非同步任務
            setTimeout(function() {
                var flag = true
                if (flag) {
                    // 正常情況
                    resolve("hello");
                } else {
                    // 異常情況
                    reject('出錯了')
                }
            }, 100)
        })

        // 第一個接收resolve裡的資訊,第二個接收reject裡的資訊
        p.then(function(data) {
            console.log(data);
        }, function(info) {
            console.log(info);
        })
    </script>
</body>

2.4 基於promise處理Ajax請求

<body>
    <script>
        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://127.0.0.1:8080/data')
        //     .then(function(data) {
        //         console.log(data);
        //     }, function(info) {
        //         console.log(info);
        //     })
        // 多個非同步任務保證順序
        queryData('http://127.0.0.1:8080/data')
            .then(function(data) {
                console.log(data);
                return queryData('http://127.0.0.1:8080/data1')
            })

        // 由上個回撥函式裡的返回呼叫
        .then(function(data) {
            console.log(data);
            return queryData('http://127.0.0.1:8080/data2')
        })

        .then(function(data) {
            console.log(data);
        })
    </script>
</body>

2.5 then引數中的函式返回值

1.返回Promise例項物件

  • 返回的該例項物件會呼叫下一個then

2.6 Promise 基本API

1.例項方法

.then()- 得到非同步任務正確的結果

.catch()- 獲取異常資訊

.finally()- 成功與否都會執行 (不是正式標準)

2.物件方法

  • .all()

Promise.all 方法接受一個數組作引數,陣列中的物件(p1、p2、p3)均為promise例項(如果不是一個
promise,該項會被用 Promise.resolve 轉換為一個promise)。它的狀態由這三個promise例項決定

  • .race()

Promise.race 方法同樣接受一個數組作引數。當p1, p2, p3中有一個例項的狀態發生改變(變為 fulfilled
或 rejected ),p的狀態就跟著改變。並把第一個改變狀態的promise的返回值,傳給p的回撥函式

Promise.all ([p1,p2,p3]).then((result) => {
console.log (result)
}
Promise.race( [p1, p2,P3]).then((result) => {
console.log (result)
}

3. fetch

3.1 fetch基本使用

基於Promise實現

<body>
    <script>
        fetch('http://127.0.0.1:8080/data')
            .then(function(data) {
                // text()屬於fetch APi中的一部分,返回一個promise例項物件,用於獲取返回的資料
                return data.text()
            })
            .then(function(data) {
                // then 解析
                console.log(data);
            })
    </script>
</body>

3.2 fetch請求引數

  1. 常用配置選項
  • method(String):HTTP請求方法,預設為GET

  • body(String):HTTP請求引數

  • headers(Object):HTTP的請求頭,預設為{}

2.get請求方式引數傳遞

// 第一種方式
// fetch('http://127.0.0.1:8080/books?id=123', {
//         method: 'get'
//     })
//     .then(function(data) {
//         // text()屬於fetch APi中的一部分,返回一個promise例項物件,用於獲取返回的資料
//         return data.text()
//     })
//     .then(function(data) {
//         // then 解析
//         console.log(data);
//     })

//第二種方式 restful風格
fetch('http://127.0.0.1:8080/books/1234', {
        method: 'get'
    })
    .then(function(data) {
        // text()屬於fetch APi中的一部分,返回一個promise例項物件,用於獲取返回的資料
        return data.text()
    })
    .then(function(data) {
        // then 解析
        console.log(data);
    })

3.post請求方式引數傳遞

fetch('http://127.0.0.1:8080/books/789', {
        method: 'delete'
    })
    .then(function(data) {
        // text()屬於fetch APi中的一部分,返回一個promise例項物件,用於獲取返回的資料
        return data.text()
    })
    .then(function(data) {
        // then 解析
        console.log(data);
    })

4.put請求方式引數傳遞

fetch('http://127.0.0.1:8080/books/123', {
                method: 'put',
                body: JSON.stringify({
                    uname: 'lisi',
                    pwd: '456'
                }),
                headers: {
                    'Content-Type': 'application/json'
                }
            })
            .then(function(data) {
                return data.text();
            }).then(function(data) {
                console.log(data)
            });

3.3 fetch響應結果

響應資料格式

  • text():將返回體處理成字串型別

  • json(): 返回結果和JSON.parse(responseText)一樣

4.axios的語法

4.1 axios的基本特性

  • 支援瀏覽器和node.js

  • 支援promise

  • 能攔截請求和響應

  • 自動轉換JSON資料

4.2 axios的基本語法

1.get和 delete請求傳遞引數

  • 通過傳統的url  以 ? 的形式傳遞引數

- restful 形式傳遞引數

- 通過params  形式傳遞引數

2.post  和 put  請求傳遞引數

  • 通過選項傳遞引數

  • 通過 URLSearchParams  傳遞引數

演示

axios.get('/adata')
	. then (ret=> {
		// data屬性名稱是固定的,用於獲取後臺響應的資料
		console.1og (ret. data )
})

4.3 axios的常用API

1.get和 delete請求傳遞引數

  • 通過傳統的url  以 ? 的形式傳遞引數

  • restful 形式傳遞引數

  • 通過params  形式傳遞引數

2.post  和 put  請求傳遞引數

  • 通過選項傳遞引數

  • 通過 URLSearchParams  傳遞引數(表單)

4.4 axios的響應結果

響應結果的主要屬性

  • data:實際響應回來的資料

  • headers:響應頭資訊

  • status:響應狀態碼

  • statusText:響應狀態資訊

4.5 axios的全域性配置

  • axios.defaults.timeout = 3000; //超時時間

  • axios.defaults.baseURL = 'ttp://127.0.0.1:8080/app'; //預設地址

  • axios.defaults.headers[ 'mytoken' ]= 'aqwerwqwerqwer2ewrwe23eresdf23' // 設定請求頭

演示

<body>
    <script src="js/axios.js"></script>	
    <script>
        // 響應結果
        // axios.get('http://127.0.0.1:8080/axios-json')
        //     .then(function(ret) {
        //         // axios已經把後臺傳來的json資料轉化了
        //         console.log(ret.data.uname);
        //     })

        // 全域性配置
        // 配置請求基準url地址
        axios.defaults.baseURL = 'http://127.0.0.1:8080/'
        axios.defaults.headers['mytoken'] = 'hello'
        axios.get('axios-json')
            .then(function(ret) {
                console.log(ret.data.uname);
            })
    </script>
</body>

4.6 axios攔截器

1.請求攔截器

  • 請求攔截器的作用是在請求傳送前進行一些操作

  • 例如在每個請求體里加上token,統一做了處理如果以後要改也非常容易

2.響應攔截器

  • 響應攔截器的作用是在接收到響應後進行一些操作

  • 例如在伺服器返回登入狀態失效,需要重新登入的時候,跳轉到登入頁

      <script type="text/javascript" src="js/axios.js"></script>
      <script type="text/javascript">
          axios.interceptors.request.use(function(config) {
              // config 資訊配置
              // 1. 傳送請求之前做些操作
              console.log(config.url);
              config.headers.mytoken = 'nihao'
              return config
          }, function(err) {
              // 對錯誤做點什麼
              console.log(err);
          })
          axios.interceptors.response.use(function(config) {
              // 在接收響應做些什麼
              var data = res.data
              return data
          }, function(err) {
              console.log(err);
          })
          axios.get('http://127.0.0.1:8080/adata')
              .then(function(data) {
                  // 拿到的是攔截器中返回的return
                  console.log(data);
              })
      </script>
    

5.1 介面呼叫 async/await語法

  1. async作為一個關鍵字放到函式前面,任何一個async函式都會隱式返回一個promise

  2. await關鍵字只能在使用async定義的函式中使用, await後面可以直接跟一個 Promise例項物件,不能單獨使用

  3. async/await 讓非同步程式碼看起來、表現起來更像同步程式碼**

await函式不能單獨使用,而且async函式返回的是一個Promise物件,可以使用then函式添加回調函式。當函式執行的時候,一旦遇到await函式就會先返回一個Promise物件,等到非同步操作完成,再去執行後面的語句

演示

<body>

    <script type="text/javascript" src="js/axios.js"></script>
    <script type="text/javascript">
        // async/await 處理非同步操作
        axios.defaults.baseURL = 'http://127.0.0.1:8080/'
            // 直接傳送的寫法
            // axios.get('axios-json')
            //     .then(function(ret) {
            //         console.log(ret.data);
            //     })

        // 非同步寫法
        // async function queryData() {
        //     var ret = await axios.get('adata')
        //     // console.log(ret.data);
        //     return ret.data
        // }

        // await後面可以直接跟一個 Promise例項物件,不能單獨使用
        async function queryData() {
            var ret = await new Promise(function(resolve, reject) {
                setTimeout(function() {
                    resolve('nihao')
                }, 1000)
            })

            // console.log(ret.data);
            return ret
        }
        queryData().then(function(data) {
            console.log(data);
        })
    </script>
</body>

5.2 async/await 處理多個非同步請求

<body>

    <script type="text/javascript" src="js/axios.js"></script>
    <script type="text/javascript">
        axios.defaults.baseURL = 'http://127.0.0.1:8080/'

        async function queryData() {
            // 順序處理等待任務
            var info = await axios.get('async1')
            var ret = await axios.get('async2?info=' + info.data)
            return ret
        }
        // 拿到返回 ret.data 
        queryData().then(function(data) {
            console.log(data.data);
            console.log(data);
        })
    </script>
</body>