Files
test1/http/type.ts
2026-03-20 07:33:46 +00:00

141 lines
3.4 KiB
TypeScript

import { get, hasIn, isNil, isString, merge, omitBy } from 'lodash-es'
import type { IStringifyOptions } from 'qs'
import qs from 'qs'
export async function defaultGetResult(response: Response) {
if (response.headers.get('content-type')?.includes('application/json')) {
const jsonData = await response.json()
if (hasIn(jsonData, 'data')) {
return jsonData.data
}
return jsonData
}
return response
}
export class HttpDefine implements Omit<RequestInit, 'body'> {
baseURL?: string
url?: string
method?: string
abort?: AbortController
timeout?: number
credentials?: RequestCredentials
ignoreError?: boolean
noRedirect?: boolean
customErrorMessage?: string
ignoreShowLimitedModal?: boolean
headers?: Record<string, any> = {
'Content-Type': 'application/json',
}
query?: Record<string, any>
// qs 序列化参数使用
querySerializer?: IStringifyOptions
body?: Record<string, any> | FormData
static hasOrigin(url: string) {
try {
const parsedUrl = new URL(url)
return parsedUrl.hostname !== ''
} catch {
// 如果 URL 无效,返回 false
return false
}
}
static mergeUrl(baseURL: string, url: string) {
if (this.hasOrigin(url)) return url
if (!baseURL) return url
let prefix = baseURL
let last = url
if (baseURL[baseURL.length - 1] === '/') {
prefix = baseURL.substring(0, baseURL.length - 1)
}
if (url[0] === '/') {
last = url.substring(1)
}
return `${prefix}/${last}`
}
static getUrl<T extends HttpDefine>(define: T = {} as any) {
const urlObj = new URL(
this.mergeUrl(define.baseURL ?? '', define.url ?? ''),
typeof window === 'object' ? window.origin : undefined,
)
const searchStr = urlObj.searchParams.toString()
const searchObj = merge(qs.parse(searchStr), define.query)
const sureSearchStr = qs.stringify(searchObj, define.querySerializer)
const base = `${urlObj.origin}${urlObj.pathname}`
if (sureSearchStr) {
return `${base}?${sureSearchStr}`
}
return base
}
static getHeader<T extends HttpDefine>(define: T = {} as any) {
const sureHeaders = omitBy(
merge({}, define.headers ?? {}),
isNil,
) as Record<string, any>
if (
get(sureHeaders, 'Content-Type', '').includes('multipart/form-data') ||
define.body instanceof FormData
) {
delete sureHeaders['Content-Type']
} else if (!get(sureHeaders, 'Content-Type', '')) {
sureHeaders['Content-Type'] = 'application/json'
}
return sureHeaders
}
static getBody<T extends HttpDefine>(define: T = {} as any) {
if (isString(define.body)) {
return define.body
}
if (define.body instanceof FormData) {
return define.body
}
if (define.body == null) return null
if (
get(define.headers, 'Content-Type', '').includes('multipart/form-data')
) {
const formData = new FormData()
Object.entries(define.body ?? []).forEach(([key, value]) => {
formData.append(key, value)
})
return formData
}
return JSON.stringify(define.body || null)
}
}
export interface HttpInjectInfo {
onRequest?: (define: HttpDefine) => Promise<HttpDefine>
onResponse?: (response: Response, define: HttpDefine) => Promise<void>
onError?: (error: Error, define: HttpDefine) => void
getResult?: (response: Response, define: HttpDefine) => Promise<any>
}