Vue學習筆記(十二) Vue Ajax

一、簡介

在 Vue.js 中咱們可使用 Axios 完成 Ajax 請求,Axios 是一個基於 Promise 的 HTTP 庫html

這篇文章的文字很少,基本都是代碼,解釋也都寫在註釋裏面啦vue

有興趣的朋友也能夠直接去看看官方文檔:http://www.axios-js.com/zh-cn/docs/java

二、安裝

(1)CDNios

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

(2)NPMshell

> npm install axios

三、GET 請求

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.js"></script>
</head>

<body>
    <div id="app">
        <p>{{ info }}</p>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                info: null
            },
            mounted: function () {
                let _this = this;
                // GET 方法原型: axios.get(url[, config])
                // 能夠在 URL 中添加參數
                axios
                    .get('http://www.httpbin.org/get?firstName=Steve&lastName=Jobs') 
                    .then(function (response) { _this.info = response.data; })
                    .catch(function (error) { console.log(error); });
            }
        })
    </script>
</body>

</html>

四、響應結構

當咱們發送請求後,接收到的響應(response)到底是個什麼東西呢?下面讓咱們來看一看npm

{
    // 服務器返回的數據
    // http://www.httpbin.org 是一個用於測試請求的網站,它所返回的數據就是咱們請求的信息
    data: {},

    // 狀態碼
    status: 200,

    // 狀態碼對應的狀態信息
    statusText: "OK",

    // 響應頭
    headers: {},

    // 爲請求提供的配置信息
    config: {}
}

五、POST 請求

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.js"></script>
</head>

<body>
    <div id="app">
        <p>{{ info }}</p>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                info: null
            },
            mounted: function () {
                let _this = this;
                // POST 方法原型: axios.post(url[, data[, config]])
                // 能夠經過 data 添加參數
                axios
                    .post('http://www.httpbin.org/post', {
                        firstName: 'Steve',
                        lastName: 'Jobs'
                    })
                    .then(function (response) { _this.info = response.data; })
                    .catch(function (error) { console.log(error); });
            }
        })
    </script>
</body>

</html>

五、請求配置

除了上面兩種常見的用法,咱們還能夠給 axios() 方法傳入一個配置對象,裏面包含用於請求的相關配置json

好比說,咱們能夠用這種方法發送一個簡單的 GET 請求:axios

axios({
    url: 'http://www.httpbin.org/get',
    method: 'get',
    params: {
        firstName: 'Steve',
        lastName: 'Jobs'
    }
})

一樣的,咱們也能夠用這種方法發送一個簡單的 POST 請求:後端

axios({
    url: 'http://www.httpbin.org/post',
    method: 'post',
    data: {
        firstName: 'Steve',
        lastName: 'Jobs'
    }
})

此外,一些比較經常使用的配置項以下:

  • url:請求 URL,惟一的必填項
  • baseURL:自動加在 url 前,以便於 url 使用相對路徑
  • method:請求方法,默認爲 get
  • headers:請求頭
  • params:請求參數
  • paramsSerializer:將 params 序列化
  • data:請求數據
  • transformRequest:在發送請求前容許修改請求數據
  • transformResponse:在接收響應前容許修改響應數據
  • timeout:指定超時時間
  • withCredentials:表示跨域請求時是否須要使用憑證,默認爲 false
  • auth:表示使用 HTTP 基礎驗證並提供憑據
  • responseType:服務器響應的數據類型,默認爲 json
  • maxContentLength:服務器響應內容的最大長度

咱們還能夠爲請求配置設置默認值:

// 例如,下面設置 baseURL 爲 https://www.example.com
axios.defaults.baseURL = 'https://www.example.com'

六、攔截器

咱們 then()catch() 以前攔截請求或響應,並對它們進行一些處理

// 添加請求攔截器
var RequestInterceptor = axios.interceptors.request.use(function (config) {
    // 對請求數據作點什麼
    return config;
}, function (error) {
    // 對請求錯誤作點什麼
    return Promise.reject(error);
});

// 添加響應攔截器
var ResponseInterceptor = axios.interceptors.response.use(function (response) {
    // 對響應數據作點什麼
    return response;
}, function (error) {
    // 對響應錯誤作點什麼
    return Promise.reject(error);
});

若是想移除攔截器,也很簡單

// 移除請求攔截器
axios.interceptors.request.eject(RequestInterceptor);

// 移除響應攔截器
axios.interceptors.response.eject(ResponseInterceptor);

七、併發請求

axios.all() 能夠批量發送請求,而後等全部請求都返回結果時,才執行一個回調

axios.all([
    asyncMethodOne(),
    asyncMethodTwo()
])
.then(axios.spread(function (resOne, resTwo) {
    // 如今兩個異步請求 asyncMethodOne 和 asyncMethodTwo 都已完成
    // resOne 和 resTwo 分別是兩個請求返回的響應
}))

補充:最近在寫 axios 的時候遇到 跨域問題,查了好久資料才最終解決,這裏也寫下來記錄一下

問題是這樣子的,就是我要在利用 @vue/cli 搭建的項目中使用 axios 請求第三方天氣查詢的接口

http://t.weather.sojson.com/api/weather/city/101280101(GET 請求,在瀏覽器打開能夠直接看到返回結果)

而後,按照上面的套路,很容易就能寫出下面的代碼:

axios
    .get('http://t.weather.sojson.com/api/weather/city/101280101')
    .then(function(res) { console.log(res); })
    .catch(function(err) { console.log(err); })

但是,當咱們運行項目 npm run serve,打開瀏覽器控制檯查看結果的時候竟然報錯了,出錯信息以下:

Access to XMLHttpRequest at 'http://t.weather.sojson.com/api/weather/city/101280101'

from origin 'http://localhost:8080' has been blocked by CORS policy:

No 'Access-Control-Allow-Origin' header is present on the requested resource.

後來在網上查了一下才知道,因爲同源策略的限制,咱們是不能直接進行跨域請求的

所謂跨域請求,是指請求 URL 與當前頁面 URL 的協議、域名、端口三者任意之一不一樣

那要怎麼解決呢?如下就是利用 @vue/cli 搭建的項目在開發環境下使用 axios 進行跨域請求的解決方案

  1. 在項目的根目錄下新建 vue.config.js 配置文件,並在文件中添加配置代碼
// vue.config.js
module.exports = {
    // 使用後端 API 服務器發送請求,這樣能夠避免跨域問題
    devServer: {
        proxy: {
            // 自定義標識符,當請求以 '/sojson' 開頭才使用代理
            '/sojson': {
                // 目標主機的協議和域名
                target: 'http://t.weather.sojson.com', 
                ws: true,
                changeOrigin: true,
                // 路徑重寫,在發送請求時將 '^/sojson' 替換成 ''
                pathRewrite: {
                    '^/sojson': ''
                }
            }
        }
    }
}
  1. 使用 axios 發送請求,注意請求地址的變化
axios
    .get('/sojson/api/weather/city/101280101')
    .then(function(res) { console.log(res); })
    .catch(function(err) { console.log(err); })

// 此時,請求 URL 爲 '/sojson/api/weather/city/101280101'
// 由於請求以 '/sojson' 開頭,符合自定義標識符,因此使用代理
// 由於請求以 '/sojson' 開頭,符合路徑重寫規則,因此將其替換爲 ''
// 拼接上目標主機的協議和域名 'http://t.weather.sojson.com'
// 最終使用代理髮送的請求爲 'http://t.weather.sojson.com/api/weather/city/101280101'
  1. 最後從新啓動項目 npm run serve(重要),就能夠實現跨域請求啦

再補充:最近又遇到一個問題,就是 GET 請求沒有問題,可是 POST 請求卻得不到正確的數據

好比說,咱們經過 POST 請求有道翻譯的接口:https://fanyi.youdao.com/translate

和上面同樣,咱們仍是須要先解決跨域的問題,在 vue.config.js 文件寫好配置就行

module.exports = {
    devServer: {
        proxy: {
            '/youdao': {
                target: 'https://fanyi.youdao.com', 
                ws: true,
                changeOrigin: true,
                pathRewrite: {
                    '^/youdao': ''
                }
            }
        }
    }
}

而後,按照上面相似的寫法使用 axios

axios({
    url: '/youdao/translate',
    method: 'POST',
    data: {
          'i': 'Hello', // 翻譯的內容
          'doctype': 'json',
          'from': 'AUTO',
          'to': 'AUTO'
    }
}).then(function(res) {
    console.log(res);
}).catch(function(err) {
    console.log(err);
})

可是當運行項目時你會發現,咱們得不到正確的數據,這時候咱們只須要作一點小改動就好

import qs from 'qs'
let fromData = {
    'i': 'Hello',
    'doctype': 'json',
    'from': 'AUTO',
    'to': 'AUTO'
}
axios({
    url: '/youdao/translate',
    method: 'POST',
    // 設置請求頭 content-type
    headers: { 'content-type': 'application/x-www-form-urlencoded' },
    // 將對象序列化爲 URL 形式
    data: qs.stringify(fromData)
}).then(function(res) {
    console.log(res);
}).catch(function(err) {
    console.log(err);
})

【 閱讀更多 Vue 系列文章,請看 Vue學習筆記

相關文章
相關標籤/搜索