Common Plugins| 请求封装规范

2024-05-04  本文已影响0人  玫瑰的lover

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)


每一年已经完成的新特性,可以在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是基于 XMLHttpRequestPromiseHTTP 请求库.
whatwg-fetch是浏览器内置的 Fetch API 的 polyfill, 可以在现代浏览器和一些旧版浏览器中兼容使用 Fetch

Axios 的内部实现是通过将 XMLHttpRequest 对象包装在一个 Promise 中来进行的。因此,当我们向服务器发送请求时,Axios 返回的是一个 Promise 对象。若该 Promise 被 resolved,则表示请求成功,否则 Promise 被 rejected,则表示请求失败

Tips

  1. 拦截器的作用
  2. Promise链式结构(this then this then that)分别用在了Axios Libraryfetch API 哪里
  3. Promise链式的错误处理(HTTP ERROR; SYSTEM ERROR;BUSINESS ERROR) (Promise.reject(error)) try catch 可以捕获同步错误和Promise.reject
  4. 请求串行,请求并行,请求轮询流程
  5. 跨域请求处理(withCredentials)
  6. 安全 xsrfHeaderName

Inspiration

interceptor
xsrf
cros

Center

拦截器分成两种,请求拦截器和响应拦截器.在请求拦截器中可以增加自定义头, 比如: request startTime. 防止跨站请求伪造攻击相关的头, xsrfHeaderName&xsrfCookieName.在响应拦截器中处理错误(system or network error); 上报接口相关信息(interface reporter)

Utils

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>
}
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()
}
  1. 通过 Request interceptorxsrfparams 塞进去
  2. 通过 requestUrl 得到新的 requestUrl
  3. 实现axios 中获取cookie中信息的逻辑, 重新组织requestOptions
  4. call window.fetch()
  5. handleResponse()
async makeRequest(){
}
  1. 重要的是call callback
async handleRequestInterceptor(){
    interceptor?.request?.(requestOptions)
}
  1. response.clone()
  2. 三目运算
    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

上一篇 下一篇

猜你喜欢

热点阅读