3

axios

 2 years ago
source link: https://kim85326.github.io/2019/10/31/axios/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

安裝 axios

  •   $ npm install --save axios
    
  •   <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

axios 特點

  1. 基本 Promise 的異步 AJAX 請求庫 (封裝 XHR)
  2. 瀏覽器端與 NodeJS 端都可以使用
  3. 支援 Request 與 Response 的攔截
  4. 支援取消 Request
  5. Request 與 Response 的資料轉換 (轉為 JSON)
  6. 批量發送多個 Request

axios 常用語法

  • axios(config)
  • axios(url[, config])
    • 指定用 GET 發送 Request
  • axios.request(config)
    • 等同於 axios(config)
  • axios.get(url[, config])
  • axios.post(url[, config])
  • axios.put(url[, config])
  • axios.delete(url[, config])
  • axios.defaults.xxx
  • axios.interceptors.request.use()
  • axios.interceptors.response.use()
  • axios.create([config])
  • axios.Cancel()
    • 取消 Request
  • axios.CancelToken()
    • 取消 Request 的 Token 物件
  • axios.isCancel()
    • 是否為一個取消 Request 的錯誤
  • axios.all(promises)
    • 用來批量執行多個異步 Request
  • axios.spread()
    • 用來指定接收所有成功資料的 callback

config

const config = {
	url: "/users", // 必填
	method: "post", // 大小寫皆可,預設是 get
	headers: { "Content-Type": "application/json" },
	baseURL: "http://localhost:3000", // 會自動加在 url 前面,除非 url 為絕對路徑
	timeout: 1000,
	data: { name: "test", title: 777 },
	params: { ID: 123 },

	// paramsSerializer 是一个負責 params 序列化的函数
	// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
	paramsSerializer: function(params) {
		return Qs.stringify(params, { arrayFormat: "brackets" });
	},

	// transformRequest 允許在發請求前,修改 Request 資料
	// 只能用在 'PUT', 'POST' 和 'PATCH'
	// 後面陣列中的函數必须回傳一个字符或 ArrayBuffer 或 Stream
	transformRequest: [
		function(data) {
			// 對 data 進行任意轉換
			return data;
		},
	],

	// transformResponse 在傳给 then/catch 前,可以修改 response 資料
	transformResponse: [
		function(data) {
			// 對 data 進行任意轉換
			return data;
		},
	],

	// 伺服器回應的數據類型
	// 選項: 'arraybuffer', 'document', 'json', 'text', 'stream'
	// 瀏覽器才有 'blob',預設為 'json'
	responseType: "json",

	// 伺服器回應的編碼模式 預設 'utf8'
	responseEncoding: "utf8",

	// 限制 Response 大小
	maxContentLength: 2000,

	// 在上傳、下載途中可執行的事情 (progressBar、Loading)
	onUploadProgress(progressEvt) {
		/* 原生 ProgressEvent */
	},
	onDownloadProgress(progressEvt) {
		/* 原生 ProgressEvent */
	},

	// xsrfCookieName 是用作 xsrf token 的值的 cookie 的名稱
	xsrfCookieName: "XSRF-TOKEN", // default

	// xsrfHeaderName 是乘載 xsrf token 的值的 HTTP Header 的名稱
	xsrfHeaderName: "X-XSRF-TOKEN", // default

	// 允許自定義處理請求,可讓測試更容易
	// return promise 並提供有效的回應 (valid response)
	adapter(config) {},

	// 表示跨域請求時是否需要使用 cookie,預設是 false
	withCredentials: false,

	// 必須提供 credentials (Cookie)
	// 等同 Authorization 表頭
	// 如果使用 token 應去 header 設置 Authorization 而非使用此
	auth: { username: "Mark", password: 123 },

	// 用來判斷是否解析 Promise 的 狀態碼範圍
	validateStatus: function(status) {
		return status >= 200 && status < 300; // default
	},

	maxRedirects: 5, // 預設為 5 次

	// xsrf token 的 Cookie名 / Header名
	xsrfCookieName: "XSRF-TOKEN", // default
	xsrfHeaderName: "X-XSRF-TOKEN", // default

	// 代理伺服器
	proxy: {
		host: "127.0.0.1",
		port: 9000,
		auth: {
			username: "mikeymike",
			password: "rapunz3l",
		},
	},

	// 用來取消請求的 token
	cancelToken: new CancelToken(function(cancel) {}),
};
{
	data: {},
	status: 200,
	statusText: "OK",
	headers: {},
	config: {}, // Request 的 config
};
axios.get('/user/12345')
  .then(function(response) {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
  });

axios.create()

  1. 創建一個實例

     const instance = axios.create({
       baseURL: 'https://some-domain.com/api/',
       timeout: 1000,
       headers: {'X-Custom-Header': 'foobar'}
     });
    	
     // 程式的某個地方再修改為
     instance.defaults.baseURL = 'https://other-domain.com/api/';
    
  2. 使用實例的方法

     instance.get('/longRequest', {
       timeout: 5000
     });
    
  • 新增攔截器

      // 新增請求攔截器
      axios.interceptors.request.use(function (config) {
          // 在發請求前做一些事
          return config;
        }, function (error) {
          // 對失敗的請求做一些事
          return Promise.reject(error);
        });
    
      // 新增回應攔截器
      axios.interceptors.response.use(function (response) {
          // 對回傳值做一些事
          return response;
        }, function (error) {
          // 對失敗的回應做一些事
          return Promise.reject(error);
        });
    
  • 新增實例的攔截器

      var instance = axios.create();
      instance.interceptors.request.use(function () {/*...*/});
    
  • 移除攔截器

      var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
      axios.interceptors.request.eject(myInterceptor);
    
var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 處理錯誤
  }
});

// 取消請求(message 參數可選)
source.cancel('Operation canceled by the user.');

併發請求 axios.all

  • 類似 Promise All 用法
  • then 後接 axios.spread
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) {
    // 兩個請求都完成
  }));

模擬實作一個簡易版的 axios

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>模擬 axios</title>
    </head>
    <body>
        <button onclick="testGet()">get</button>
        <button onclick="testPost()">post</button>
        <button onclick="testPut()">put</button>
        <button onclick="testDelete()">delete</button>
        <script>
            function axios({ url, method = "GET", params = {}, data = {} }) {
                method = method || "GET";
                method = method.toUpperCase();

                let query = [];
                Object.keys(params).forEach((key) => {
                    query.push(`${key}=${params[key]}`);
                });
                const queryString = query.join("&");

                url += `?${queryString}`;

                return new Promise((resolve, reject) => {
                    const xhr = new XMLHttpRequest();
                    xhr.open(method, url, true);
                    xhr.responseType = "json";

                    xhr.onreadystatechange = () => {
                        if (xhr.readyState !== 4) {
                            return;
                        }

                        if (xhr.status >= 200 && xhr.status < 300) {
                            const response = {
                                data: xhr.response,
                                status: xhr.status,
                                statusText: xhr.statusText,
                            };
                            resolve(response);
                        } else {
                            reject(
                                new Error(
                                    "請求失敗 status code = " + xhr.status
                                )
                            );
                        }
                    };

                    if (method === "GET" || method === "DELETE") {
                        xhr.send(null);
                    } else {
                        xhr.setRequestHeader(
                            "Content-Type",
                            "application/json;charset=utf-8"
                        );
                        xhr.send(JSON.stringify(data));
                    }
                });
            }

            function testGet() {
                axios({
                    url: "http://localhost:3000/users",
                    // url: "http://localhost:3000/users1",
                    params: { age: 18, gender: "female" },
                })
                    .then((response) => {
                        console.log("get 成功", response.data, response);
                    })
                    .catch((error) => {
                        console.log("get 失敗", error.message);
                    });
            }

            function testPost() {
                axios({
                    url: "http://localhost:3000/users",
                    // url: "http://localhost:3000/users1",
                    method: "POST",
                    data: { name: "john", age: 30, gender: "male" },
                })
                    .then((response) => {
                        console.log("post 成功", response.data, response);
                    })
                    .catch((error) => {
                        console.log("post 失敗", error.message);
                    });
            }

            function testPut() {
                axios({
                    url: "http://localhost:3000/users/1",
                    // url: "http://localhost:3000/users1",
                    method: "PUT",
                    data: { name: "andy", age: 1, gender: "male" },
                })
                    .then((response) => {
                        console.log("put 成功", response.data, response);
                    })
                    .catch((error) => {
                        console.log("put 失敗", error.message);
                    });
            }

            function testDelete() {
                axios({
                    url: "http://localhost:3000/users/1",
                    // url: "http://localhost:3000/users1",
                    method: "DELETE",
                })
                    .then((response) => {
                        console.log("delete 成功", response.data, response);
                    })
                    .catch((error) => {
                        console.log("delete 失敗", error.message);
                    });
            }
        </script>
    </body>
</html>

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK