日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

antd request 通过jsessionid传参数_Umi-request源码阅读

發(fā)布時間:2023/12/4 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 antd request 通过jsessionid传参数_Umi-request源码阅读 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近參照antd-pro腳手架進行開發(fā),因此接觸到了umi-request。

umijs/umi-request?github.com

umi-request對fetch進行了封裝,簡化了api的使用,結合了fetch和axios的特點,具體可參照umi-request的readme介紹。

文件結構

核心文件夾為src文件夾,內含

  • lib文件夾為修改后的fetch.js;
  • defaultInterceptor.js用于注冊攔截器;
  • index.js是外部調用的入口文件;
  • request.js提供request實例;
  • utils.js定義了處理緩存、請求異常、響應異常、處理gbk、json語法分析的功能類;
  • wrapped-fetch.js從文件名可以看出來為封裝fetch,實現(xiàn)更新版數(shù)據(jù)的傳遞;
  • wrapped-rpc.js從文件可以看出封裝了rpc通信,待實現(xiàn);

代碼分析

原始代碼里含的注釋基本上已經很全面了

defaultInterceptor.js

功能有:數(shù)據(jù)提交方式簡化/針對常見兩種數(shù)據(jù)傳輸格式補全文件頭“Accept: 'application/json', 'Content-Type': 'application/json(或者x-www-form-urlencoded);charset=UTF-8'”/url 參數(shù)自動序列化

主要是對傳入的url和option進行格式化的處理,以便后續(xù)的fetch.js進行處理。
關于option的新增參數(shù)參見request.js。export default (url, originOptions = {}) => {const options = { ...originOptions };// 默認get, 兼容method大小寫let method = options.method || 'get';method = method.toLowerCase();if (method === 'post' || method === 'put' || method === 'patch' || method === 'delete') {// requestType 簡寫默認值為 jsonconst { requestType = 'json', data } = options;// 數(shù)據(jù)使用類axios的新字段data, 避免引用后影響舊代碼, 如將body stringify多次if (data) {const dataType = Object.prototype.toString.call(data);if (dataType === '[object Object]' || dataType === '[object Array]') {if (requestType === 'json') {options.headers = {Accept: 'application/json','Content-Type': 'application/json;charset=UTF-8',...options.headers,};options.body = JSON.stringify(data);} else if (requestType === 'form') {options.headers = {Accept: 'application/json','Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',...options.headers,};options.body = stringify(data);}} else {// 其他 requestType 自定義headeroptions.headers = {Accept: 'application/json',...options.headers,};options.body = data;}}}// 支持類似axios 參數(shù)自動拼裝, 其他method也可用, 不沖突.if (options.params && Object.keys(options.params).length > 0) {const str = url.indexOf('?') !== -1 ? '&' : '?';url = `${url}${str}${stringify(options.params)}`;}return {url,options,}; };

fetch.js

主要是定義了request和response攔截器。

攔截器,在AOP(Aspect-Oriented Programming)中用于在某個方法或字段被訪問之前,進行攔截,然后在之前或之后加入某些操作。可以對http請求進行批量處理。import 'whatwg-fetch'; import defaultInterceptor from '../defaultInterceptor';const requestInterceptors = []; export const responseInterceptors = [];function fetch(url, options = {}) {if (typeof url !== 'string') throw new Error('url MUST be a string');// 執(zhí)行 request 的攔截器,使用defaultInterceptor,依據(jù)handler方式對url,option進行處理requestInterceptors.concat([defaultInterceptor]).forEach(handler => {const ret = handler(url, options);url = ret.url || url;options = ret.options || options;});// 將 method 改為大寫options.method = options.method ? options.method.toUpperCase() : 'GET';// 請求數(shù)據(jù)let response = window.fetch(url, options);// 執(zhí)行 response 的攔截器,依據(jù)handler方式對url,option進行處理responseInterceptors.forEach(handler => {response = response.then(res => handler(res, options));});return response; } // 支持攔截器,參考 axios 庫的寫法: https://github.com/axios/axios#interceptors fetch.interceptors = {request: {use: handler => {requestInterceptors.push(handler);},},response: {use: handler => {responseInterceptors.push(handler);},}, };export default fetch;

utils.js

定義了處理緩存(Mapcache)、請求異常(RequestError)、響應異常(ResponseError)、處理gbk(readerGBK)、json語法轉換(safeJsonParse)的功能類;

  • 處理緩存

options.maxCache是option的extend參數(shù),可以在封裝umi-request時指定,

如antd-pro. const request = extend({maxCache: 50,});

實現(xiàn)變量的獲取、變量刪除、緩存清空、value存入緩存(其中key json化后為關鍵字)

export class MapCache {constructor(options) {this.cache = new Map();this.timer = {};this.maxCache = options.maxCache || 0;}get(key) {return this.cache.get(JSON.stringify(key));}set(key, value, ttl = 60000) {// 如果超過最大緩存數(shù), 刪除頭部的第一個緩存.if (this.maxCache > 0 && this.cache.size >= this.maxCache) {const deleteKey = [...this.cache.keys()][0];this.cache.delete(deleteKey);if (this.timer[deleteKey]) {clearTimeout(this.timer[deleteKey]);}}const cacheKey = JSON.stringify(key);this.cache.set(cacheKey, value);if (ttl > 0) {this.timer[cacheKey] = setTimeout(() => {this.cache.delete(cacheKey);delete this.timer[cacheKey];}, ttl);}}delete(key) {const cacheKey = JSON.stringify(key);delete this.timer[cacheKey];return this.cache.delete(cacheKey);}clear() {this.timer = {};return this.cache.clear();} }

在wrapped-fetch.js中調用

_wrappedCache(instance, useCache) {if (useCache) {const { params, ttl } = this.options;//url請求參數(shù)params,和緩存時長ttl為option傳入參數(shù)return instance.then(response => {// 只緩存狀態(tài)碼為 200的數(shù)據(jù)if (response.status === 200) {const copy = response.clone();copy.useCache = true;//this.cache為通過request.js調用傳入的參數(shù)const mapCache = new MapCache(initOptions);this.cache.set({ url: this.url, params }, copy, ttl);}return response;});} else {return instance;} }
  • 請求異常
export class RequestError extends Error {constructor(text) {super(text);this.name = 'RequestError';} }

在wrapped-fetch.js中如此使用,用于輸出超時信息,其中timeout為option傳入參數(shù)。需要注意的是超時后客戶端雖然返回超時, 但api請求不會斷開, 寫操作慎用。

return Promise.race([new Promise((_, reject) =>setTimeout(() => reject(new RequestError(`timeout of ${timeout}ms exceeded`)), timeout)),instance, ]);
  • 響應異常
export class ResponseError extends Error {constructor(response, text, data) {super(text || response.statusText);this.name = 'ResponseError';this.data = data;this.response = response;} }

在wrapped-fetch.js中調用,示例,當異常時拋出異常

catch (e) {throw new ResponseError(response, e.message);}
  • 支持gbk并進行json格式的轉換

判斷返回的數(shù)據(jù)時表示gbk編碼的,如果是,將數(shù)據(jù)以gbk格式讀入,然后再利用safeJsonParse轉化為json格式

export function readerGBK(file) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => {resolve(reader.result);};reader.onerror = reject;reader.readAsText(file, 'GBK'); // setup GBK decoding}); }export function safeJsonParse(data) {try {return JSON.parse(data);} catch (e) {} // eslint-disable-linereturn data; }

wrappedfetch.js

核心部分,基于fetch進行數(shù)據(jù)交互

一個 Promise 就是一個對象,它代表了一個異步操作的最終完成或者失敗,通過 .then() 形式添加的回調函數(shù),連續(xù)執(zhí)行兩個或者多個異步操作(鏈式調用,多個then,一個catch接收異常)。

一個 Promise有以下幾種狀態(tài):

  • pending: 初始狀態(tài),既不是成功,也不是失敗狀態(tài)。
  • fulfilled: 意味著操作成功完成。
  • rejected: 意味著操作失敗。

當其中任一種情況出現(xiàn)時,Promise 對象的 then 方法綁定的處理方法(handlers )就會被調用(then方法包含兩個參數(shù):onfulfilled 和 onrejected,它們都是 Function 類型。當Promise狀態(tài)為fulfilled時,調用 then 的 onfulfilled 方法,當Promise狀態(tài)為rejected時,調用 then 的 onrejected 方法。

Promise.resolve(value)方法返回一個以給定值解析后的Promise 對象。但如果這個值是個thenable(即帶有then方法),返回的promise會“跟隨”這個thenable的對象,采用它的最終狀態(tài)(指resolved/rejected/pending/settled);如果傳入的value本身就是promise對象,則該對象作為Promise.resolve方法的返回值返回;否則以該值為成功狀態(tài)返回promise對象。

Promise.reject(reason)返回一個狀態(tài)為失敗的Promise對象,并將給定的失敗信息傳遞給對應的處理方法

export default class WrappedFetch {constructor(url, options, cache) {this.cache = cache;//cache是MapCache的實例this.url = url;this.options = options;this._addfix();return this._doFetch();}_doFetch() {//如果使用cache,只有在option的method是get且useCache為true時使用cacheif (useCache) {let response = this.cache.get({url: this.url,params: this.options.params,});if (response) {response = response.clone();let instance = Promise.resolve(response);responseInterceptors.forEach(handler => {instance = instance.then(res => handler(res, this.options));});return this._parseResponse(instance, true);}}let instance = fetch(this.url, this.options);// 處理超時instance = this._wrappedTimeout(instance);// 處理緩存 1.只有get 2.同時參數(shù)cache為true 才緩存instance = this._wrappedCache(instance, useCache);// 返回解析好的數(shù)據(jù)return this._parseResponse(instance);}//對url進行自動序列化,添加前綴和后綴_addfix() {} //調用RequestError,在超時后輸出信息_wrappedTimeout(instance) {}//調用MapCache,在用戶使用usecache時將response復制到擦車中,并設置緩存時間_wrappedCache(instance, useCache) {}//處理返回類型, 并解析數(shù)據(jù),如果編碼方式時gbk則利用readerGBK和safeJsonParse進行轉化,在讀取response時,加入responseError處理_parseResponse(instance, useCache = false) {}//處理錯誤_handleError({ reject, resolve }, error) {} }

request.js

option里支持的參數(shù)有:(較fetch增加的)

* @param {string} requestType post類型, 用來簡化寫content-Type, 默認json
* @param {*} data post數(shù)據(jù)
* @param {object} params query參數(shù)
* @param {string} responseType 服務端返回的數(shù)據(jù)類型, 用來解析數(shù)據(jù), 默認json
* @param {boolean} useCache 是否使用緩存,只有get時有效, 默認關閉, 啟用后如果命中緩存, response中有useCache=true. 另: 內存緩存, 刷新就沒。一個簡單的Map cache, 提供session local map三種前端cache方式.
* @param {number} ttl 緩存生命周期, 默認60秒, 單位毫秒
* @param {number} timeout 超時時長, 默認未設, 單位毫秒
* @param {boolean} getResponse 是否獲取response源
* @param {function} errorHandler 錯誤處理
* @param {string} prefix 前綴
* @param {string} suffix 后綴
* @param {string} charset 字符集, 默認utf8

extend里支持的參數(shù)有:

* @param {number} maxCache 最大緩存數(shù)
* @param {string} prefix url前綴
* @param {function} errorHandler 統(tǒng)一錯誤處理方法
* @param {object} headers 統(tǒng)一的headers

method包括:'get', 'post', 'delete', 'put', 'patch','rpc'。其中,'get', 'post', 'delete', 'put', 'patch'屬于REST風格,是http協(xié)議的一種直接應用,默認基于json作為傳輸格式,使用簡單,學習成本低效率高。RPC是指遠程過程調用直觀說法就是A通過網絡調用B的過程方法,是分布式系統(tǒng)中常見的方法。

  • GET操作是安全且等冪的。所謂安全是指不管進行多少次操作,資源的狀態(tài)都不會改變。
  • PUT,DELETE操作是冪等的。所謂冪等是指不管進行多少次操作,結果都一樣。比如我用PUT修改一篇文章,然后在做同樣的操作,每次操作后的結果并沒有不同,DELETE也是一樣。
  • POST操作既不是安全的,也不是冪等的,比如常見的POST重復加載問題:當我們多次發(fā)出同樣的POST請求后,其結果是創(chuàng)建出了若干的資源。
安全和冪等的意義在于:當操作沒有達到預期的目標時,我們可以不停的重試,而不會對資源產生副作用。從這個意義上說,POST操作需要謹慎。還有一點需要注意的就是,創(chuàng)建操作可以使用POST,也可以使用PUT,區(qū)別在于POST 是作用在一個集合資源之上的(/uri),而PUT操作是作用在一個具體資源之上的(/uri/xxx),再通俗點說,如果URL可以在客戶端確定,那么就使用PUT,如果是在服務端確定,那么就使用POST,比如說很多資源使用數(shù)據(jù)庫自增主鍵作為標識信息,而創(chuàng)建的資源的標識信息到底是什么只能由服務端提供,這個時候就必須使用POST。
  • PATCH新引入的,是對PUT方法的補充,用來對已知資源進行局部更新。在沒有patch之前,我們都是用put進行更新操作,這時候我們的接口中通常會有一個邏輯規(guī)則,如:如果對象的的一個字符屬性為NULL,那么就是不更新該屬性(字段)值,如果對象的字符屬性是“”,那么就更新該屬性(字段)的值,通過這種方式來避免全部覆蓋的操作。現(xiàn)在有了patch就解決了這種判斷,在put接口中不管屬性是不是null,都進行更新,在patch接口中就對非null的進行更新
import fetch from './lib/fetch'; import { MapCache } from './utils'; import WrappedFetch from './wrapped-fetch'; import WrappedRpc from './wrapped-rpc';/*** 獲取request實例 調用參數(shù)可以覆蓋初始化的參數(shù). 用于一些情況的特殊處理.* @param {*} initOptions 初始化參數(shù)*/ const request = (initOptions = {}) => {const mapCache = new MapCache(initOptions);const instance = (input, options = {}) => {options.headers = { ...initOptions.headers, ...options.headers };options.params = { ...initOptions.params, ...options.params };options = { ...initOptions, ...options };const method = options.method || 'get';options.method = method.toLowerCase();if (method === 'rpc') {// call rpcreturn new WrappedRpc(input, options, mapCache);} else {return new WrappedFetch(input, options, mapCache);}};// 增加語法糖如: request.get request.post// 對應著對資源的查看,創(chuàng)建,刪除,創(chuàng)建或更新,部分更新,rpcconst methods = ['get', 'post', 'delete', 'put', 'patch','rpc',];methods.forEach(method => {instance[method] = (input, options) => instance(input, { ...options, method });});// 給request 也增加一個interceptors引用;instance.interceptors = fetch.interceptors;return instance; };/*** extend 方法參考了ky, 讓用戶可以定制配置.* initOpions 初始化參數(shù)* @param {number} maxCache 最大緩存數(shù)* @param {string} prefix url前綴* @param {function} errorHandler 統(tǒng)一錯誤處理方法* @param {object} headers 統(tǒng)一的headers*/ export const extend = initOptions => request(initOptions); export default request();

使用示例

通過extend進行簡單封裝,參照antd-pro,dva數(shù)據(jù)流處理方式。

import { extend } from 'umi-request'; ...... const request = extend({errorHandler, // 默認錯誤處理函數(shù)credentials: 'include', // 默認請求是否帶上cookie// useCache: false,// maxCache: 50, }); export default request;

后續(xù)在api.js中的使用

import request from '@/utils/request'; //get請求 export async function function1({ classId }) {return request(`/api/classes/${classId}/teachers/`);} //post請求 export async function function2({ classId }) {return request.post('/api/classes/${classId}/teachers/', { data: {foo: 'bar'}});} // 使用緩存 export async function function3({ classId }) {return request(`/api/classes/${classId}/teachers/`, { useCache: true, ttl: 10000 });}

每一個頁面對應的model中,可以通過下面的方式進行使用

* fetchBasic({ classId }, { call, put }) {//利用call方式調用api.js中聲明的function1 const response = yield call(fuction1, classId);//對接收到的response進行處理yield put({type: 'saveResponse',//reducers中對應的處理方法payload: response}); },

特點

  • url 參數(shù)自動序列化
  • post 數(shù)據(jù)提交方式簡化
  • response 返回處理簡化
  • api 超時支持
  • api 請求緩存支持
  • 支持處理 gbk
  • 類 axios 的 request 和 response 攔截器(interceptors)支持
更多內容查看umi-request項目、dva文檔、antd-pro項目umi-request項目?github.comDva 概念 | DvaJS?dvajs.comantd-pro項目?github.com

總結

以上是生活随笔為你收集整理的antd request 通过jsessionid传参数_Umi-request源码阅读的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。