withCredentials
接口修改
// ./src/type/index.ts
//...
export interface AxiosRequestConfig {
url?: string
method?: Method
data?: any
params?: any
headers?: any
responseType?: XMLHttpRequestResponseType
timeout?: number
transformRequest?: AxiosTransformer | AxiosTransformer[]
transformResponse?: AxiosTransformer | AxiosTransformer[]
cancelToken?: CancelToken
withCredentials?: boolean
[propName: string]: any
}
//...
逻辑实现
// ./src/core/xhr.ts
import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from '../types'
import { parseHeaders } from '../helpers/headers'
import { createError } from '../helpers/error'
export default function xhr(config: AxiosRequestConfig): AxiosPromise {
return new Promise((resolve, reject) => {
const { data = null, url, method = 'get', headers, responseType, timeout, cancelToken, withCredentials } = config
const request = new XMLHttpRequest()
if (responseType) {
request.responseType = responseType
}
if (timeout) {
request.timeout = timeout
}
if (withCredentials) {
request.withCredentials = withCredentials
}
//...
})
}
测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="/__build__/more.js"></script>
</body>
</html>
// ./examples/more/app.ts
import axios from '../../src/index'
document.cookie = 'a=b'
axios.get('/more/get').then(res => {
console.log(res)
})
axios.post('http://127.0.0.1:8088/more/server2', {}, {
withCredentials: true
}).then(res => {
console.log(res)
})
跨域服务
// ./examples/server2.js
const express = require('express')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(cookieParser())
const router = express.Router()
const cors = {
'Access-Control-Allow-Origin': 'http://localhost:8080',
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Methods': 'POST, GET, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
}
router.post('/more/server2', (req, res) => {
res.set(cors)
res.json(req.cookies)
})
router.options('/more/server2', function(req, res) {
res.set(cors)
res.end()
})
app.use(router)
const port = 8088
module.exports = app.listen(port)
服务2启动
// ./examples/server.js
const express = require('express')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const webpack = require('webpack')
const webpackDevMiddleware = require('webpack-dev-middleware')
const webpackHotMiddelware = require('webpack-hot-middleware')
const WebpackConfig = require('./webpack.config')
require('./server2')
const app = new express()
const compiler = webpack(WebpackConfig)
app.use(webpackDevMiddleware(compiler, {
publicPath: '/__build__/',
stats: {
colors: true,
chunks: false
}
}))
app.use(webpackHotMiddelware(compiler))
app.use(express.static(__dirname))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
app.use(cookieParser())
const router = express.Router()
//...
router.get('/more/get', (req, res) => {
res.json(req.cookies)
})
app.use(router)
const port = process.env.PORT || 8080
module.exports = app.listen(port, () => {
console.log(`Serve listening on http://localhost:${port}, Ctrl + C to stop`)
})
XSRF防御
修改类型
// ./src/type/index.ts
export interface AxiosRequestConfig {
url?: string
method?: Method
data?: any
params?: any
headers?: any
responseType?: XMLHttpRequestResponseType
timeout?: number
transformRequest?: AxiosTransformer | AxiosTransformer[]
transformResponse?: AxiosTransformer | AxiosTransformer[]
cancelToken?: CancelToken
withCredentials?: boolean
xsrfCookieName?: string
xsrfHeaderName?: string
[propName: string]: any
}
添加默认值
// ./src/default.ts
const defaults: AxiosRequestConfig = {
//...
xsrfCookieName: 'XSRF_TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
//...
}
判断是否同源
// ./src/helpers/url.ts
import { isDate, isPlainObject } from './util'
interface URLOrigin {
protocol: string
host: string
}
//...
export function isURLSameOrigin(requestURL: string): boolean {
const parsedOrigin = resolveURL(requestURL)
return (parsedOrigin.protocol === currentOrigin.protocol && parsedOrigin.host == currentOrigin.host)
}
const urlParsingNode = document.createElement('a')
const currentOrigin = resolveURL(window.location.href)
function resolveURL(url: string): URLOrigin {
urlParsingNode.setAttribute('href', url)
const { protocol, host } = urlParsingNode
return {
protocol,
host
}
}
处理cookie
// ./src/helpers/cookie.ts
const cookie = {
read(name: string):string | null {
const match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'))
return match? decodeURIComponent(match[3]) : null
}
}
export default cookie
完善逻辑
// ./src/core/xhr.ts
import { isURLSameOrigin } from '../helpers/url'
import cookie from '../helpers/cookie'
export default function xhr(config: AxiosRequestConfig): AxiosPromise {
return new Promise((resolve, reject) => {
//...
if ((withCredentials || isURLSameOrigin(url!)) && xsrfCookieName) {
const xsrfValue = cookie.read(xsrfCookieName)
if (xsrfValue && xsrfHeaderName) {
headers[xsrfHeaderName] = xsrfValue
}
}
//...
})
}
测试
// ./examples/more/app.ts
import axios from '../../src/index'
const instance = axios.create({
xsrfCookieName: 'XSRF-TOKEN-D',
xsrfHeaderName: 'X-XSRF-TOKEN-D'
})
instance.get('/more/get').then(res => {
console.log(res)
})
// ./examples/server.js
//...
app.use(webpackHotMiddelware(compiler))
app.use(express.static(__dirname, {
setHeaders (res) {
res.cookie('XSRF-TOKEN-D', '1234abc')
}
}))
//...
上传和下载的进度监控
类型定义
// ./src/type/index.ts
export interface AxiosRequestConfig {
url?: string
method?: Method
data?: any
params?: any
headers?: any
responseType?: XMLHttpRequestResponseType
timeout?: number
transformRequest?: AxiosTransformer | AxiosTransformer[]
transformResponse?: AxiosTransformer | AxiosTransformer[]
cancelToken?: CancelToken
withCredentials?: boolean
xsrfCookieName?: string
xsrfHeaderName?: string
onDownloadProgress?: (e: ProgressEvent) => void
onUploadProgress?: (e: ProgressEvent) => void
[propName: string]: any
}
逻辑实现
// ./src/core/xhr.ts
import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from '../types'
import { parseHeaders } from '../helpers/headers'
import { createError } from '../helpers/error'
import { isURLSameOrigin } from '../helpers/url'
import cookie from '../helpers/cookie'
import { isFormData } from '../helpers/util'
export default function xhr(config: AxiosRequestConfig): AxiosPromise {
return new Promise((resolve, reject) => {
//...
if (onDownloadProgress) {
request.onprogress = onDownloadProgress
}
if (onUploadProgress) {
request.upload.onprogress = onUploadProgress
}
if (isFormData(data)) {
delete headers['Content-Type']
}
//...
})
}
工具函数
// ./src/helpers/util.ts
export function isFormData (val: any): val is FormData {
return typeof val !== 'undefined' && val instanceof FormData
}
整理代码
// ./src/core/xhr.ts
import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from '../types'
import { parseHeaders, processHeaders } from '../helpers/headers'
import { createError } from '../helpers/error'
import { isURLSameOrigin } from '../helpers/url'
import cookie from '../helpers/cookie'
import { isFormData } from '../helpers/util'
export default function xhr(config: AxiosRequestConfig): AxiosPromise {
return new Promise((resolve, reject) => {
const {
data = null,
url,
method = 'get',
headers,
responseType,
timeout,
cancelToken,
withCredentials,
xsrfCookieName,
xsrfHeaderName,
onDownloadProgress,
onUploadProgress
} = config
const request = new XMLHttpRequest()
request.open(method.toUpperCase(), url!, true)
configureRequest()
addEvents()
processHeaders()
processCancel()
request.send(data)
function configureRequest(): void {
if (responseType) {
request.responseType = responseType
}
if (timeout) {
request.timeout = timeout
}
if (withCredentials) {
request.withCredentials = true
}
}
function addEvents(): void {
request.onreadystatechange = function handleLoad() {
if (request.readyState !== 4) {
return
}
if (request.status === 0) {
return
}
const responseHeaders = parseHeaders(request.getAllResponseHeaders())
const responseData = responseType !== 'text' ? request.response : request.responseText
const response: AxiosResponse = {
data: responseData,
status: request.status,
statusText: request.statusText,
headers: responseHeaders,
config,
request
}
handleResponse(response)
}
request.onerror = function handleError() {
reject(createError('Network Error', config, null, request))
}
request.ontimeout = function handleTimeout() {
reject(createError(`Timeout of ${timeout} ms exceeded`, config, 'ECONNABORTED', request))
}
if (onDownloadProgress) {
request.onprogress = onDownloadProgress
}
if (onUploadProgress) {
request.upload.onprogress = onUploadProgress
}
}
function processHeaders(): void {
if (isFormData(data)) {
delete headers['Content-Type']
}
if ((withCredentials || isURLSameOrigin(url!)) && xsrfCookieName) {
const xsrfValue = cookie.read(xsrfCookieName)
if (xsrfValue && xsrfHeaderName) {
headers[xsrfHeaderName] = xsrfValue
}
}
Object.keys(headers).forEach(name => {
if (data === null && name.toLowerCase() === 'content-type') {
delete headers[name]
} else {
request.setRequestHeader(name, headers[name])
}
})
}
function processCancel(): void {
if (cancelToken) {
cancelToken.promise.then(reason => {
request.abort()
reject(reason)
})
}
}
function handleResponse(response: AxiosResponse): void {
if (response.status >= 200 && response.status < 300) {
resolve(response)
} else {
reject(
createError(
`Request failed with status code ${response.status}`,
config,
null,
request,
response
)
)
}
}
})
}
测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>More</title>
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/>
</head>
</head>
<body>
<h1>File download</h1>
<div>
<button id="download" class="btn btn-primary">DownLoad</button>
</div>
<h1>File upload</h1>
<div>
<form role="form" class="form" onsubmit="return false;">
<input id="file" type="file" class="form-control">
<button id="upload" type="button" class="btn btn-primary">Upload</button>
</form>
</div>
<script src="/__build__/more.js"></script>
</body>
</html>
npm i nprogress
npm i @types/nprogress
npm i style-loader
npm i css-loader
配置webpack
const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
module.exports = {
//...
module: {
rules: [
//..
{
test: /\.css$/,
use: [
'style-loader', 'css-loader'
]
}
]
},
//...
}
// ./examples/more/app.ts
import axios from '../../src/index'
import 'nprogress/nprogress.css'
import NProgress from 'nprogress'
const instance = axios.create()
function calculatePercentage (loaded: number, total: number) {
return Math.floor(loaded * 1.0) / total
}
function loadProgressBar() {
const setupStartProgress = () => {
instance.interceptors.request.use(config => {
NProgress.start()
return config
})
}
const setupUpdateProgress = () => {
const update = (e: ProgressEvent) => {
console.log(e)
NProgress.set(calculatePercentage(e.loaded, e.total))
}
instance.defaults.onDownloadProgress = update
instance.defaults.onUploadProgress = update
}
const setupStopProgress = () => {
instance.interceptors.response.use(response => {
NProgress.done()
return response
}, error => {
NProgress.done()
return Promise.reject(error)
})
}
setupStartProgress()
setupUpdateProgress()
setupStopProgress()
}
loadProgressBar()
const downloadEl = document.getElementById('download')
downloadEl!.addEventListener('click', e => {
instance.get('https://img.mukewang.com/5cc01a7b0001a33718720632.jpg')
})
const uploadEl = document.getElementById('upload')
uploadEl.addEventListener('click', e => {
const data = new FormData()
const fileEl = document.getElementById('file') as HTMLInputElement
if (fileEl.files) {
data.append('file', fileEl.files[0])
instance.post('/more/upload', data)
}
})
npm i connect-multiparty
// ./examples/server.js
const path = require('path')
const multipart = require('connect-multiparty')
app.use(multipart({
uploadDir: path.resolve(__dirname, 'upload-file')
}))
const router = express.Router()
router.post('/more/upload', (req, res) => {
console.log(req.body, req.files)
res.end('upload success!')
})
app.use(router)
const port = process.env.PORT || 8080
module.exports = app.listen(port, () => {
console.log(`Serve listening on http://localhost:${port}, Ctrl + C to stop`)
})
HTTP授权
类型定义
// ./src/type/index.ts
//...
export interface AxiosRequestConfig {
url?: string
method?: Method
data?: any
params?: any
headers?: any
responseType?: XMLHttpRequestResponseType
timeout?: number
transformRequest?: AxiosTransformer | AxiosTransformer[]
transformResponse?: AxiosTransformer | AxiosTransformer[]
cancelToken?: CancelToken
withCredentials?: boolean
xsrfCookieName?: string
xsrfHeaderName?: string
onDownloadProgress?: (e: ProgressEvent) => void
onUploadProgress?: (e: ProgressEvent) => void
auth?: AxiosBasicCredentials
[propName: string]: any
}
//...
export interface AxiosBasicCredentials {
username: string
password: string
}
合并配置
// ./src/core/mergeConfig.ts
//..
const stratKeysDeepMerge = ['headers', 'auth']
//..
修改逻辑
// ./src/core/xhr.ts
//...
export default function xhr(config: AxiosRequestConfig): AxiosPromise {
return new Promise((resolve, reject) => {
const {
data = null,
url,
method = 'get',
headers,
responseType,
timeout,
cancelToken,
withCredentials,
xsrfCookieName,
xsrfHeaderName,
onDownloadProgress,
onUploadProgress,
auth
} = config
//...
function processHeaders(): void {
//...
if (auth) {
headers['Authorization'] = `Basic ${btoa(`${auth.username}:${auth.password}`)}`
}
//...
}
//...
})
}
测试
// ./examples/more/app.ts
import axios from '../../src/index'
import 'nprogress/nprogress.css'
import NProgress from 'nprogress'
axios.post('/more/post', {
a: 1
}, {
auth: {
username: 'Jack',
password: 'test'
}
}).then(res => {
console.log(res)
})
// ./examples/server.js
//...
const router = express.Router()
router.post('/more/post', (req, res) => {
const auth = req.headers.authorization
const [type, credentials] = auth.split(' ')
console.log(atob(credentials))
const [username, password] = atob(credentials).split(':')
if (type === 'Basic' && username === 'Jack' && password === 'test') {
res.json(req.body)
} else {
res.status(401)
res.end('UnAuthorization')
}
})
app.use(router)
const port = process.env.PORT || 8080
module.exports = app.listen(port, () => {
console.log(`Serve listening on http://localhost:${port}, Ctrl + C to stop`)
})
自定义合法状态码
扩展接口
// ./src/type/index.ts
export interface AxiosRequestConfig {
url?: string
method?: Method
data?: any
params?: any
headers?: any
responseType?: XMLHttpRequestResponseType
timeout?: number
transformRequest?: AxiosTransformer | AxiosTransformer[]
transformResponse?: AxiosTransformer | AxiosTransformer[]
cancelToken?: CancelToken
withCredentials?: boolean
xsrfCookieName?: string
xsrfHeaderName?: string
onDownloadProgress?: (e: ProgressEvent) => void
onUploadProgress?: (e: ProgressEvent) => void
auth?: AxiosBasicCredentials
validateStatus?: (status: number) => boolean
[propName: string]: any
}
设置默认配置
// ./src/default.ts
//...
const defaults: AxiosRequestConfig = {
//...
validateStatus(status: number): boolean {
return status >= 200 && status < 300
}
}
修改逻辑
// ./src/core/xhr.ts
import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from '../types'
import { parseHeaders, processHeaders } from '../helpers/headers'
import { createError } from '../helpers/error'
import { isURLSameOrigin } from '../helpers/url'
import cookie from '../helpers/cookie'
import { isFormData } from '../helpers/util'
export default function xhr(config: AxiosRequestConfig): AxiosPromise {
return new Promise((resolve, reject) => {
const {
data = null,
url,
method = 'get',
headers,
responseType,
timeout,
cancelToken,
withCredentials,
xsrfCookieName,
xsrfHeaderName,
onDownloadProgress,
onUploadProgress,
auth,
validateStatus
} = config
//...
function handleResponse(response: AxiosResponse): void {
if (!validateStatus || validateStatus(response.status)) {
resolve(response)
} else {
reject(
createError(
`Request failed with status code ${response.status}`,
config,
null,
request,
response
)
)
}
}
})
}
测试
// ./examples/more/app.ts
import axios from '../../src/index'
import 'nprogress/nprogress.css'
import NProgress from 'nprogress'
import { AxiosError } from '../../src/helpers/error'
axios.get('/more/304').then(res => {
console.log(res)
}).catch((e: AxiosError) => {
console.log(e.message)
})
axios.get('/more/304', {
validateStatus(status) {
return status >= 200 && status < 400
}
}).then(res => {
console.log(res)
}).catch((e: AxiosError) => {
console.log(e.message)
})
自定义参数序列化
扩展接口
// ./src/type/index.ts
export interface AxiosRequestConfig {
url?: string
method?: Method
data?: any
params?: any
headers?: any
responseType?: XMLHttpRequestResponseType
timeout?: number
transformRequest?: AxiosTransformer | AxiosTransformer[]
transformResponse?: AxiosTransformer | AxiosTransformer[]
cancelToken?: CancelToken
withCredentials?: boolean
xsrfCookieName?: string
xsrfHeaderName?: string
onDownloadProgress?: (e: ProgressEvent) => void
onUploadProgress?: (e: ProgressEvent) => void
auth?: AxiosBasicCredentials
validateStatus?: (status: number) => boolean
paramsSerializer?: (params: any) => string
[propName: string]: any
}
处理逻辑实现
// ./src/helpers/url.ts
import { isDate, isPlainObject, isURLSearchParams } from './util'
//...
export function buildURL(url: string, params?: any, paramsSerializer?: (params: any) => string): string {
if (!params) {
return url
}
let serializedParams
if (paramsSerializer) {
serializedParams = paramsSerializer(params)
} else if (isURLSearchParams(params)) {
serializedParams = params.toString()
} else {
const parts: string[] = []
Object.keys(params).forEach(key => {
const val = params[key]
if (val === null || typeof val === 'undefined') {
return
}
let values = []
if (Array.isArray(val)) {
values = val
key += '[]'
} else {
values = [val]
}
values.forEach(val => {
if (isDate(val)) {
val = val.toISOString()
} else if (isPlainObject(val)) {
val = JSON.stringify(val)
}
parts.push(`${encode(key)}=${encode(val)}`)
})
})
serializedParams = parts.join('&')
}
if (serializedParams) {
const markIndex = url.indexOf('#')
if (markIndex !== -1) {
url = url.slice(0, markIndex)
}
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
}
return url
}
//...
// ./src/helpers/util.ts
export function isURLSearchParams (val: any): val is URLSearchParams {
return typeof val !== 'undefined' && val instanceof URLSearchParams
}
接入使用
// ./src/core/dispatchRequest.ts
//...
function transformURL(config: AxiosRequestConfig): string {
const { url, params, paramsSerializer } = config
return buildURL(url!, params, paramsSerializer)
}
测试
// ./examples/more/app.ts
import axios from '../../src/index'
import 'nprogress/nprogress.css'
import NProgress from 'nprogress'
import { AxiosError } from '../../src/helpers/error'
import qs from 'qs'
axios.get('/more/get', {
params: new URLSearchParams('a=b&b=c')
}).then(res => {
console.log(res)
})
axios.get('/more/get', {
params: {
a: 1,
b: 2,
c: ['a','b','c']
}
}).then(res => {
console.log(res)
})
const instance = axios.create({
paramsSerializer (params) {
return qs.stringify(params, { arrayFormat: 'brackets'})
}
})
instance.get('/more/get', {
params: {
a: 1,
b: 2,
c: ['a', 'b', 'c']
}
}).then(res => {
console.log(res)
})
baseURL
接口扩展
// ./src/type/index.ts
export interface AxiosRequestConfig {
url?: string
method?: Method
data?: any
params?: any
headers?: any
responseType?: XMLHttpRequestResponseType
timeout?: number
transformRequest?: AxiosTransformer | AxiosTransformer[]
transformResponse?: AxiosTransformer | AxiosTransformer[]
cancelToken?: CancelToken
withCredentials?: boolean
xsrfCookieName?: string
xsrfHeaderName?: string
onDownloadProgress?: (e: ProgressEvent) => void
onUploadProgress?: (e: ProgressEvent) => void
auth?: AxiosBasicCredentials
validateStatus?: (status: number) => boolean
paramsSerializer?: (params: any) => string
baseURL?: string
[propName: string]: any
}
处理逻辑
// ./src/helpers/url.ts
export function isAbsoluteURL(url: string): boolean {
return /(^[a-z][a-z\d\+\-\.]*:)?\/\//i.test(url)
}
export function combineURL(baseURL: string, relativeURL?: string): string {
return relativeURL? `${baseURL.replace(/\/+$/, '')}/${relativeURL.replace(/^\/+/, '')}` : baseURL
}
使用
// ./src/core/dispatchRequest.ts
function transformURL(config: AxiosRequestConfig): string {
let { url, params, paramsSerializer, baseURL } = config
if (baseURL && !isAbsoluteURL(url!)) {
url = combineURL(baseURL, url)
}
return buildURL(url!, params, paramsSerializer)
}
测试
// ./examples/more/app.ts
import axios from '../../src/index'
const instance = axios.create({
baseURL: 'https://img.mukewang.com'
})
instance.get('5cc01a7b0001a33718720632.jpg')
instance.get('https://img.mukewang.com/szimg/5becd5ad0001b89306000338-360-202.jpg')
静态方法扩展
接口修改
// ./src/type/index.ts
export interface Axios {
defaults: AxiosRequestConfig
interceptors: {
request: AxiosInterceptorManager<AxiosRequestConfig>
response: AxiosInterceptorManager<AxiosResponse>
}
request<T = any>(config: AxiosRequestConfig): AxiosPromise<T>
get<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>
delete<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>
head<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>
options<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>
post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>
put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>
patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>
getUri(config?:AxiosRequestConfig): string
}
export interface AxiosClassStatic {
new(config: AxiosRequestConfig): Axios
}
export interface AxiosStatic extends AxiosInstance {
create(config?: AxiosRequestConfig): AxiosInstance
CancelToken: CancelTokenStatic
Cancel: CancelStatic
isCancel: (value: any) => boolean
all<T>(promises: Array<T | Promise<T>>): Promise<T[]>
spread<T, R>(callback: (...arg: T[]) => R): (arr: T[]) => R
Axios: AxiosClassStatic
}
接口实现
// ./src/index.ts
// ...
axios.all = function all(promises){
return Promise.all(promises)
}
axios.spread = function spread(callback) {
return function wrap(arr) {
return callback.apply(null, arr)
}
}
axios.Axios = Axios
export default axios
// ./src/core/Axios.ts
//...
export default class Axios {
//...
getUri(config: AxiosRequestConfig): string {
config = mergeConfig(this.defaults, config)
return transformURL(config)
}
//...
}
测试
// ./examples/more/app.ts
import axios from '../../src/index'
function getA() {
return axios.get('/more/A')
}
function getB () {
return axios.get('/more/B')
}
axios.all([getA(), getB()])
.then(axios.spread((resA, resB) => {
console.log(resA.data)
console.log(resB.data)
}))
axios.all([getA(), getB()])
.then(([resA, resB]) => {
console.log(resA.data)
console.log(resB.data)
})
const fakeConfig = {
baseURL: 'https://www.baidu.com/',
url: '/user/12345',
params: {
idClient: 1,
idTest: 2,
testString: 'thisIsTest'
}
}
console.log(axios.getUri(fakeConfig))
router.get('/more/A', (req,res) => {
res.end('A')
})
router.get('/more/B', (req,res) => {
res.end('B')
})