141 lines
3.4 KiB
TypeScript
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>
|
|
} |