Common Plugins| 请求封装规范
Previous on fetch data
W3C(World Wide Web Consortium)是一个国际性的标准化组织,致力于推动 Web 技术的发展和标准化。
WHATWG(Web Hypertext Application Technology Working Group)是一个由若干个大型科技公司组成的联盟,旨在推动 Web 标准的发展,并提高网页技术的互操作性和可扩展性。
AJAX(Asynchronous JavaScript and XML)是用于 Web 开发的技术, 可以在不重新加载整个页面的情况下,对页面的部分内容进行更新和动态加载
XML(Extensible Markup Language)是一种标记语言, 用于描述数据和数据之间的关系。
ES5; ES6(ECMAScript 2015) ; ES7(ECMAScript 2016) ... ES12(JavaScript ES2021)
- ES6(历经
15年才发布) - ES7 array.prototype.includes(); 指数操作符号; decorator
- ES8 async/await; Object.values ;Object.entries; padStart()
- ES9 Promise.prototype.finally(); 可以使用
for-await-of循环遍历异步操作的结果;Rest/Spread; Array.prototype.flatMap() - ES10
Array.flat();Array.flatMap();Object.fromEntries();String.trimStart();Symbol.description - ES11 可选链运算符
?.; 空值合并运算符??;BigInt类型;Promise.allSettled();String.prototype.matchAll() - ES12 数字分隔符
(const million = 1_000_000;);WeakRefs(const cache = new WeakMap());Promise.any()
每一年已经完成的新特性,可以在mdn查看 https://github.com/tc39/proposals/blob/HEAD/finished-proposals.md
https://ecma-international.org/
toSort() vs sort
2024- Object.groupBy()
2022- new Error(e, cause: '')
2022- findLast
AJAX
AJAX是一种前端编程模式,用于实现异步数据交互且无需刷新整个网页,动态局部更新网页.AJAX 的核心是使用 JS 发送异步HTTP请求来获取数据.通过XMLHttpRequest对象与服务器进行异步通信,并根据返回的数据动态更新页面内容,而不需要刷新整个页面.
XMLHttpRequest
使用callbacks方式处理服务器响应. 从 IE6 开始支持,也就是说浏览器的支持性好
Fetch
使用Promise方式处理服务器响应.是ES6新增的函数,需要额外兼容处理(whatwg-fetch)
axios & whatwg-fetch
axios是基于 XMLHttpRequest 和 Promise 的 HTTP 请求库.
whatwg-fetch是浏览器内置的 Fetch API 的 polyfill, 可以在现代浏览器和一些旧版浏览器中兼容使用 Fetch
Axios 的内部实现是通过将 XMLHttpRequest 对象包装在一个 Promise 中来进行的。因此,当我们向服务器发送请求时,Axios 返回的是一个 Promise 对象。若该 Promise 被 resolved,则表示请求成功,否则 Promise 被 rejected,则表示请求失败
Tips
- 拦截器的作用
Promise链式结构(this then this then that)分别用在了Axios Library和fetch API哪里Promise链式的错误处理(HTTP ERROR;SYSTEM ERROR;BUSINESS ERROR) (Promise.reject(error)) try catch 可以捕获同步错误和Promise.reject- 请求串行,请求并行,请求轮询流程
- 跨域请求处理(
withCredentials)- 安全 xsrfHeaderName
Inspiration
interceptor
xsrf
cros
Center
拦截器分成两种,请求拦截器和响应拦截器.在请求拦截器中可以增加自定义头, 比如: request startTime. 防止跨站请求伪造攻击相关的头, xsrfHeaderName&xsrfCookieName.在响应拦截器中处理错误(system or network error); 上报接口相关信息(interface reporter)
Utils
- 从
Url获取指定的搜索参数(window.location.search), such asaadvid. 核心代码是qs.parse -
judgment+hash
function getUrlQuery (param?:string): string| Record<string, string>{
const queries = querystring.parse(window.location.search) ?? {};
if(param){
return (queries[param]?? '') as string
}
return queries as Record<string, string>
}
- 从
Url提取携带参数, 返回(对应path, 合并后的参数集合,以及新的Url).核心是qs.stringify
function urlParser(url: sting, params:Record<string, unknown>): [string,Record<string, unknown>, string]{
let path = url;
let query = params;
if(url.includes('?')){
path = url.slice(零, url.indexOf('?'));
query = Object.assign(qs.parse(url.slice(url.indexOf('?'))), params)
}
const newUrl = `${path}?${qs.stringify(query)}`;
return [path, query, newUrl]
}
Request Library related to fetch
使用
const xxxRequest = new HTTPClient(
interceptor: {
request: (config) => {return config};
response: (response) => {return response};
}
)
实现
HTTPClient
class HTTPClient{
baseUrl?: string; // 这是类自身的参数
options?: IOptions; // 这是类自身的参数
constructor(options?:IOptions){
const {baseUrl = ' ', ...extraOptions} = options || {};
this.baseUrl = baseUrl;
this.options = extraOptions;
}
> 1. 先将默认头塞进去,两个`key`是`content-type` 和`accept`
> 2. 调用`makeRequest`
> 3. 返回 `result`
```js
get( ) {
return this.makeRequest()
}
- 通过 Request interceptor将
xsrf和params塞进去- 通过
requestUrl得到新的requestUrl- 实现axios 中获取cookie中信息的逻辑, 重新组织
requestOptions- call window.fetch()
- handleResponse()
async makeRequest(){
}
- 重要的是call callback
async handleRequestInterceptor(){
interceptor?.request?.(requestOptions)
}
- response.clone()
- 三目运算
async handleResponse(){}
response.ok? 存在响应拦截器,返回处理结果: 直接返回处理结果
}
Ajax Library related to Axios
有很多封装好的功能,比如跨域, 防止
CSRF攻击的头xsrf cookie name
拦截器直接使用ajax.interceptors.request.use
Code
const ajax = axios.create({
withCredentials: true
})
ajax.interceptors.request.use(config => {
const adv = getUrlQuery('aadvid');
config.data = {
aadvid,
... config.data
}
config.xsrfCookieName = 'csrftoken';
config.xsrfHeaderName = 'X-CSRFToken';
if (config.method === 'get') {
config.params = config.data;
delete config.data;
} else if (config.method === 'post') {
config.params = { aadvid };
// 即将被发送的自定义的请求头
config.headers['Content-Type'] = 'application/json';
}
return {
...config,
};
},
error => Promise.reject(error),
)
ajax.interceptors.response.use(
response => response.data,
error => Promise.reject(error),
);
export default <T>(config: AxiosRequestConfig) =>
ajax.request<T, IRequestRes<T>>(config);
// 接口统一定义数据
interface IRequestRes<T> {
extra?: { i18n_key: string };// 额外信息
code: number; // 业务状态码
message: string; // 错误信息
data: T; // 业务数据
}
Additional
window.location.reload( )window.location.hrefwindow.location.search-
window.location.pathname最后是否存在反斜杠/可以直接使用string.split,判断分割后的最后一个string -
string的常用方法slice和substring,其中最大的区别在 一个处理负数一个不处理负数