必然会用到的 axios 中自带的工具方法
侧边栏壁纸
  • 累计撰写 1,061 篇文章
  • 累计收到 0 条评论

必然会用到的 axios 中自带的工具方法

加速器之家
2024-10-20 / 0 评论 / 3 阅读 / 正在检测是否收录...

在 axios 中,使用到了很多基础的工具方法,这些方法我们也可以提炼下,看是否能应用到我们自己的实际项目中。

1. 是否是绝对链接 #

所谓的绝对链接指的是有协议的链接,例如https://, weixin://, file://等,或者只有//开头的链接,都属于绝对链接,其他的则属于相对链接。

/**
* Determines whether the specified URL is absolute
*
* @param {string} url The URL to test
* @returns {boolean} True if the specified URL is absolute, otherwise false
*/
module.exports = function isAbsoluteURL(url) { // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed // by any combination of letters, digits, plus, period, or hyphen. return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url); };

2. 将 baseURL 和 requestedURL 拼接成一个 URL #

这里通常 baseURL 是比较固定的,在写配置时,可以只写 requestedURL 部分,然后再将 baseURL 和 requestedURL 拼接成一个完成的 URL。

在完成这个功能之前,我们首先要实现将一个 url 合法的前后部分拼接起来的方法,这里假定所有的传入都是合法的,是因为在调用该方法前已经做好了判断:

/**
* Creates a new URL by combining the specified URLs
*
* @param {string} baseURL The base URL
* @param {string} relativeURL The relative URL
* @returns {string} The combined URL
*/
module.exports = function combineURLs(baseURL, relativeURL) { // 将baseURL最后的斜杠和relativeURL最前面的斜杠去掉 return relativeURL ? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "") : baseURL; };

这时,再要拼接 baseURL 和 requestedURL 时,就要判断 baseUrl 是否存在,或者 path 是否是一个绝对链接,只有在 baseURL 存在,且 requestedURL 不是绝对链接时,才将 baseURL 和 requestedURL 拼接到一起:

/**
* Creates a new URL by combining the baseURL with the requestedURL,
* only when the requestedURL is not already an absolute URL.
* If the requestURL is absolute, this function returns the requestedURL untouched.
*
* @param {string} baseURL The base URL
* @param {string} requestedURL Absolute or relative URL to combine
* @returns {string} The combined full path
*/
module.exports = function buildFullPath(baseURL, requestedURL) { if (baseURL && !isAbsoluteURL(requestedURL)) { return combineURLs(baseURL, requestedURL); } return requestedURL; };

在使用 url 之前,先调用下buildFullPath方法,就可以确定这一定是一个绝对链接(要保证 baseURL 和 requestURL 至少有 1 个是绝对链接)。

3. 迭代执行数据中的每一项 #

我们有时会对一个 array 类型或者 object 类型的数据进行循环迭代,执行同一个操作,例如编码其中的每一项等。但在不知道数据类型的前提下,我们可以使用下面的这个方法:

/**
* Iterate over an Array or an Object invoking a function for each item.
*
* If `obj` is an Array callback will be called passing
* the value, index, and complete array for each item.
*
* If 'obj' is an Object callback will be called passing
* the value, key, and complete object for each property.
*
* @param {Object|Array} obj The object to iterate
* @param {Function} fn The callback to invoke for each item
*/
function forEach(obj, fn) { // Don't bother if no value provided // 如果为空则直接返回 if (obj === null || typeof obj === "undefined") { return; } // Force an array if not already something iterable // 如果既不是array类型,也不是object类型,则将其放到一个数据中 // 方便进行循环处理 if (typeof obj !== "object") { /*eslint no-param-reassign:0*/ obj = [obj]; } // 这里isArray采用 Object.prototype.toString.call 进行判断 // Object.prototype.toString.call(obj) === '[object Array]' if (isArray(obj)) { // Iterate over array values // 迭代数据中的每一项 for (var i = 0, l = obj.length; i < l; i++) { fn.call(null, obj[i], i, obj); } } else { // Iterate over object keys // 迭代object类型数据中的每一项 for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { fn.call(null, obj[key], key, obj); } } } }

4. 将 object 类型的参数拼接到 url 后面 #

我们在开发过程中,object 类型的数据操作起来比较方便,但在进行 get 请求时或者需要打开带参数的 URL 时,都需要把 object 类型的数据进行转换。实现这个功能最常见的库就是qs了:

import { stringify } from "qs";

const params = {
    name: "wenzi",
    score: "98",
    company: "tencent",
};

// qs中的stringify自带编码
console.log(stringify(params)); // name=wenzi&score=98&company=tencent

在 axios 中,为了方便进行用户进行配置,这里改为了根据用户传入的数据变换方式来处理数据:

function encode(val) {
    return encodeURIComponent(val).replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",").replace(/%20/g, "+").replace(/%5B/gi, "[").replace(/%5D/gi, "]");
}

/**
* Build a URL by appending params to the end
*
* @param {string} url 要拼接的基本url
* @param {object} [params] 将要追加的参数
* @returns {string} 已拼接好的URL
*/
module.exports = function buildURL(url, params, paramsSerializer) { /*eslint no-param-reassign:0*/ // 若没有参数,则不需要拼接,直接返回url接口 if (!params) { return url; } var serializedParams; if (paramsSerializer) { // 若用户传入了变换数据的函数,则执行 serializedParams = paramsSerializer(params); } else if (utils.isURLSearchParams(params)) { // 若是一个URLSearchParams类型的数据,直接转为string类型 serializedParams = params.toString(); } else { var parts = []; // params是其他类型时 // 对params进行循环 utils.forEach(params, function serialize(val, key) { if (val === null || typeof val === "undefined") { return; } if (utils.isArray(val)) { // 若值是一个数据,则后端可能就是要接收数组格式的数据 // 这里把key添加一个[] key = key + "[]"; } else { // 将val设置为数组,继续循环 val = [val]; } utils.forEach(val, function parseValue(v) { if (utils.isDate(v)) { v = v.toISOString(); } else if (utils.isObject(v)) { v = JSON.stringify(v); } parts.push(encode(key) + "=" + encode(v)); }); }); // 取出的所有的参数进行拼接 serializedParams = parts.join("&"); } if (serializedParams) { // 判断url中是否存在hash路径,若存在,则只获取前面的部分 var hashmarkIndex = url.indexOf("#"); if (hashmarkIndex !== -1) { url = url.slice(0, hashmarkIndex); } // 拼接 url += (url.indexOf("?") === -1 ? "?" : "&") + serializedParams; } return url; };

5. 总结 #

这些工具方法虽然是 axios 中的,但我们平时中用到的也比较多,这里提炼出来,也希望能给大家在平时开发中,提供一些帮助。

0

评论

博主关闭了当前页面的评论