# Axios3 (Third HTTP Client Variant) > Latest HTTP client with AxiosOptions interface and flexible response filtering. ## File `plugs/http/axios3.ts` --- ## Overview Third and most refined iteration. Introduces `AxiosOptions` interface for flexible request options and `filter` callback for custom response processing. --- ## Key Improvements over Axios2 | Feature | Axios2 | Axios3 | |---------|--------|--------| | Options interface | `noMsg?, noLoading?` as positional | `AxiosOptions` object | | Response filter | Built-in only | Customizable via `filter` option | | Query params merging | Simple params | `mergeQueryParams()` | | Success detection | `response.success` only | Multiple indicators | | URLSearchParams support | No | Yes | --- ## AxiosOptions Interface ```typescript export interface AxiosOptions { noMsg?: boolean | null; noLoading?: boolean | null; filter?: (response) => any; query?: QueryParams; } type QueryParams = URLSearchParams | Record | ConstructorParameters[0]; ``` ### Options Properties | Property | Type | Purpose | |----------|------|---------| | `noMsg` | `boolean \| null` | Suppress success/error messages | | `noLoading` | `boolean \| null` | Suppress loading indicator | | `filter` | `(response) => any` | Custom response transformation | | `query` | `QueryParams` | Additional query parameters to merge | --- ## Axios Instance Configuration ```typescript const config = { baseURL: process.env.VUE_APP_BASE_URL ? "/api" : "", timeout: 60 * 1000, withCredentials: true, }; const _axios = axios.create(config); ``` --- ## Registration Functions ```typescript export const registerBaseUrl = (url) => { _axios.defaults.baseURL = url; }; export const registerRouter = (routerP) => { router = routerP; }; ``` --- ## Request Interceptor Located at `plugs/http/axios3.ts` lines 29-48: ```typescript _axios.interceptors.request.use( function (config) { const time = new Date().getTime().toString(); const params = new URLSearchParams(config.params); if (params.toString()) { delEmpty(params); params.append("t", time); config.params = params; } const data = config.data; if (data != null && typeof data === "object") { delEmpty(data); data.t = time; } return config; }, function (error) { return Promise.reject(error); } ); ``` ### Key Difference Uses `URLSearchParams` for params manipulation, ensuring proper encoding. --- ## delEmpty Function (Enhanced) Located at `plugs/http/axios3.ts` lines 50-65: ```typescript function delEmpty(data) { if (data && data instanceof URLSearchParams) { for (const [k, v] of data.entries()) { if (!v) data.delete(k); } } else if (data && typeof data === "object") { for (const item in data) { if (data.hasOwnProperty(item)) { const val = data[item]; if ((val == null || val == "null" || val == "") && val !== 0 && val !== false) { delete data[item]; } } } } } ``` ### Enhanced Behavior - Handles `URLSearchParams` natively - Also deletes empty strings for `false` values --- ## Default Response Filter ```typescript const defaultFilterResp = (resp) => { const isSuccess = resp.success || resp.status === "ok" || resp.status === "success" || resp.data != null; const isError = resp.success === false || resp.status === "error"; if (isSuccess) { return resp.data ? resp.data : resp; } else if (isError) { return false; } else return resp; }; ``` ### Success Detection Logic Accepts any of these as success: - `response.success === true` - `response.status === "ok"` - `response.status === "success"` - `response.data != null` Returns `response.data` on success, `false` on error, raw response otherwise. --- ## Query Params Merging ```typescript function mergeQueryParams(...params: Array) { const res: URLSearchParams = new URLSearchParams(); for (const param of params) { if (param == null) continue; let parsed; if (param instanceof URLSearchParams) { parsed = param; } else { parsed = new URLSearchParams(param); } parsed .entries() .filter(([k, v]) => v != null && v != "null" && v != "undefined" && v != "") .forEach(([k, v]) => res?.append(k, v)); } return res ?? new URLSearchParams(); } ``` ### Features - Merges multiple query param sources - Filters out `null`, `"null"`, `"undefined"`, and empty strings - Supports both `URLSearchParams` and plain objects --- ## Export Methods with AxiosOptions | Method | Signature | Purpose | |--------|-----------|---------| | `post` | `(url, data?, options?: AxiosOptions)` | POST request | | `get` | `(url, data?: QueryParams, options?: AxiosOptions)` | GET request | | `put` | `(url, data?, options?: AxiosOptions)` | PUT request | | `delate` | `(url, data?, options?: AxiosOptions)` | DELETE request | | `upload` | `(file, url, data)` | File upload | | `getFile` | `(url, data?, options?: AxiosOptions)` | Download as blob | | `download` | `(fileName, url, data, callBack?)` | Browser download | | `registerBaseUrl` | `(url)` | Set base URL | | `registerRouter` | `(routerP)` | Set router | --- ## Response Handler with Filter ```typescript function handResponse(response, resolve, options: AxiosOptions = {}) { if (!options.noLoading) { close(); } const filterResponse = options.filter ?? defaultFilterResp; const result = filterResponse(response); if (result) { if (!options.noMsg && response.message) { showMessage("success", response.message); } resolve(result); } else { // Error handling with router redirect if (response.message == "session timeout") { router?.push("/login"); response.message = t("http.unLogin"); } if (response.message == "no permission") { response.message = t("http.unPermission"); } if (response.message?.indexOf("no permission for ") == 0) { response.message = t("http.noPermission"); } if (!options.noMsg && response.message) { showMessage("error", response.message); } response.error && console.log(response.error); resolve(false); } } ``` --- ## Usage Examples ### Basic GET with options ```typescript import { Axios3 } from '@/plugs/http'; const data = await Axios3.get('/api/users', { page: 1 }, { noLoading: true }); ``` ### GET with query merging ```typescript const data = await Axios3.get('/api/search', { keyword: 'test' }, { query: { sort: 'name' } }); // Results in: /api/search?keyword=test&sort=name ``` ### Custom filter ```typescript const result = await Axios3.post('/api/custom', data, { filter: (response) => { if (response.code === 200) { return response.result; } return false; } }); ``` --- ## Anti-Patterns 1. **`delate` function name** - Should be `delete` 2. **Resolves `false` for errors** - Inconsistent with promise conventions 3. **`noMsg` not passed to error handler** - Error messages always shown regardless of `noMsg` setting