txios
一个基于 Promise 的 HTTP 库,使用 TypeScript 封装,可在常规浏览器上使用
注意: txios
是基于 Rollup
进行编译打包,但是在项目构建阶段依然采用了 Webpack 4.x
,其中的调试命令请参考 package.json
中的 script
选项
项目在线 demo 为 --> 在 Vue 中引入 txios
:warning: 目前项目暂不支持 Node.js,未来将会继续推出 txios 的 Node 版本
功能支持
- 支持使用 XMLHttpRequest 对象通信
- 支持 Promise API
- 支持请求/响应拦截以及其过程中的数据转换
- 支持取消请求
- 支持自动转换 JSON 数据
- 客户端支持 XSRF 防御
浏览器支持
安装
使用 npm
npm install txios
使用 yarn
yarn add txios
使用 cdn
<script src="https://cdn.jsdelivr.net/npm/txios@0.1.0/dist/txios.umd.min.js"></script>
例子
注意:ES6 模块引入
为了得到 TypeScript 的类型,你可以做如下的写法
import txios from 'txios'
发送一个 GET
请求
import txios from 'txios'
txios.get('/foo?name=strugglebak')
.then(response => {
})
.catch(error => {
})
.finally(() => {
})
txios.get('/foo', {
params: {
name: 'strugglebak'
}
})
.then(response => {
})
.catch(error => {
})
.finally(() => {
})
如果你也想使用 async/await 语法
async function findFoo() {
try {
const response = await txios.get('/foo?name=strugglebak')
console.log(response)
} catch (error) {
console.log(error)
}
}
注意: async/await 语法属于 ES7 的,所以这里并不支持一些 老旧的浏览器 以及 老大难 IE
发送一个 POST
请求
txios.post('/foo', {
name: 'strugglebak',
age: 18
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
并行发送多个请求
function getFoo1() {
return txios.get('/foo/strugglebak/1')
}
function getFoo2() {
return txios.get('/foo/strugglebak/2')
}
txios.all([getFoo1(), getFoo2()])
.then(txios.spread((response1, response2) => {
console.log('getFoo1', response1)
console.log('getFoo2', response2)
}))
txios.all([getFoo1(), getFoo2()])
.then(([response1, response2]) => {
console.log('getFoo1', response1)
console.log('getFoo2', response2)
})
txios 相关 API
通过传配置的方式发送请求
txios(config)
txios({
method: 'post',
url: '/foo/strugglebak',
data: {
name: 'strugglebak',
age: 18
}
});
txios(url[, config])
txios('/foo/strugglebak')
请求方法 API
所有请求方法都有对应的 HTTP 请求名
txios.get(url[, config])
txios.delete(url[, config])
txios.head(url[, config])
txios.options(url[, config])
txios.post(url[, data[, config]])
txios.put(url[, data[, config]])
txios.patch(url[, data[, config]])
当然还有
txios.request(url[, config])
注意
在使用这种 HTTP 别名的方式来发送请求时(不包括 request
),config
属性不需要加 url
、method
、data
属性
在使用 request
时,不需要加 url
属性
并发请求
有两个 API 可以帮助你实现并发请求
txios.all(iterable)
txios.spread(callback)
创建实例
你可以使用 自定义配置 去创建一个 txios 实例
txios.create([config])
const instance = txios.create({
baseUrl: 'https://github.com',
timeout: 500,
headers: {
'X-COMMON-HEADER': 'foo'
}
})
实例方法
同样的,instance 实例都具有 txios 里面的方法, 同时传参数的方式都是一样的
txios#request(config)
txios#get(url[, config])
txios#delete(url[, config])
txios#head(url[, config])
txios#options(url[, config])
txios#post(url[, data[, config]])
txios#put(url[, data[, config]])
txios#patch(url[, data[, config]])
txios#getUri([config])
请求配置
在如下的请求配置项中,只有 url
属性是 必填 的,其他的配置项都是可选的
{
url: '/foo',
method: 'get',
params: 'strugglebak',
data: 'strugglebak',
responseType: 'arraybuffer',
timeout: 1000,
transformRequest: [(data) => {
return data
}],
transformResponse: [(data) => {
return data
}],
cancelToken: new CancelToken(c => {}),
withCredentials: true,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
onDownloadProgress: (progressEvent) => {
},
onUploadProgress: (progressEvent) => {
},
auth: {
username: 'strugglebak',
password: '123456'
},
validateStatus: (status) => {
return status >= 200 && status < 400
},
paramsSerializer: (params) => {
return params
},
baseUrl: 'https://github.com'
}
响应数据的格式
{
data: {},
status: 200,
statusText: 'OK',
headers: {},
config: {},
request: {}
}
当使用 then
时,你会得到
txios.get('/foo/strugglebak')
.then(response => {
console.log(response.data)
console.log(response.status)
console.log(response.statusText)
console.log(response.headers)
console.log(response.config)
})
当然,若你使用 catch
或者在 then
中传 reject
回调, response
将会在 error
中访问到,相关章节请访问 错误处理
默认配置
你可以给每个请求搞个默认的配置
全局默认配置
txios.defaults.headers.common['xxx'] = XXX
txios.defaults.headers.post['Content-Type'] = 'application/json'
txios.defaults.baseUrl = 'https://github.com'
自定义实例配置
const instance = axios.create({
baseUrl: 'https://github.com'
});
instance.defaults.headers.common['XXX'] = XXX
配置的优先级
后面配置的将会比前面配置的优先级高,因为默认配置项在合并时,会遵从 defalut.ts
-> instance
里的配置 -> config
参数里面的配置这样的顺序,以下是一个例子
const instance = txios.create()
instance.defaults.timeout = 1000
instance.get('/foo', {
timeout: 10
})
拦截器
在 then
或者 catch
之前对请求或者响应进行拦截
txios.interceptors.request.use(
config => {
return config
},
error => {
return Promise.reject(error)
})
txios.interceptors.response.use(
res => {
return res
},
error => {
return Promise.reject(error)
})
同时你也可以删除一个拦截器
const interceptorId = txios.interceptors.response.use(res => {
return res
})
txios.interceptors.response.eject(interceptorId)
也可以同时添加多个拦截器
txios.interceptors.request.use(config => {
config.headers.test += 'request interceptor 1'
return config
});
txios.interceptors.request.use(config => {
config.headers.test += 'request interceptor 2'
return config
})
txios.interceptors.request.use(config => {
config.headers.test += 'request interceptor 3'
return config
})
txios.interceptors.response.use(res => {
res.data += 'response interceptor 1'
return res
})
txios.interceptors.response.use(res => {
res.data += 'response interceptor 2'
return res
})
txios.interceptors.response.use(res => {
res.data += 'response interceptor 3'
return res
})
错误处理
txios.get('/foo/strugglebak')
.catch(error => {
console.log(error.config);
console.log(error.code);
console.log(error.request);
console.log(error.isTxiosError)
console.log(error.response)
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
})
可以使用 validateStatus
配置项来决定接受到哪些 HTTP 状态码才抛出异常
txios('/foo/strugglebak', {
validateStatus: (status) => {
return < 200
}
})
取消请求
你可以通过一个 cancel token
来取消请求
通过使用 CancelToken.source
这个工厂函数,你可以创建一个 cancel token
const CancelToken = txios.CancelToken
const source = CancelToken.source()
txios.get('/cancel/get', {
cancelToken: source.token
}).catch(e => {
if (txios.isCancel(e)) console.log('Request canceled', e.message)
})
setTimeout(() => {
source.cancel('Operation canceled by the user.')
txios.post('/cancel/post', { a: 1 }, { cancelToken: source.token })
.catch(e => {
if (txios.isCancel(e)) console.log(e.message)
})
}, 100)
其中 isCancel
是判断这个错误参数 e
是不是一次取消请求导致的错误
你还可以通过在 CancelToken
构造函数中传一个执行函数的形式来创建一个 cancel token
let cancel: Canceler
txios.get('/cancel/get', {
cancelToken: new CancelToken(c => { cancel = c })
}).catch(e => {
if (txios.isCancel(e)) console.log('Request canceled')
})
setTimeout(() => { cancel() }, 200)
建议
使用 application/x-www-form-urlencoded 格式
默认情况下,txios 会将 JS 对象转换成 JSON
, 所以如果你想要以 application/x-www-form-urlencoded
的形式发送数据,最好这样做
浏览器端
你可以使用 URLSearchParams
这个 API
const params = new URLSearchParams()
params.append('param1', 'value1')
params.append('param2', 'value2')
txios.post('/foo', params)
注意 URLSearchParams
这个 API 并不是被所有浏览器支持的,请酌情使用哈~,相关兼容性请去看 caniuse
或者你可以使用 qs
这个库
import qs from 'qs'
txios.post('/foo', qs.stringify({ name: 'strugglebak' }))
Promises
txios 依赖于原生 ES6 Promise 实现, 如果贵环境还不支持 ES6 语法,你可以试试 es6-promise
License
MIT