更新支持注入

master
yutent 2022-03-22 19:04:58 +08:00
parent 6909c15ffb
commit 8ad97d1e1d
5 changed files with 137 additions and 51 deletions

10
.prettierrc.yaml Normal file
View File

@ -0,0 +1,10 @@
jsxBracketSameLine: true
jsxSingleQuote: true
semi: false
singleQuote: true
printWidth: 100
useTabs: false
tabWidth: 2
trailingComma: none
bracketSpacing: true
arrowParens: avoid

View File

@ -59,7 +59,7 @@ f1('/get_list', {body: {page: 1}})
> 发起一个网络请求, options的参数如下。 同时支持配置公共域名, 公共参数。
+ method<String> 默认GET, 可选GET/POST/PUT/DELETE...
+ body<Any> 要发送的数据, 如果是GET方式, 会被自动拼接到url上
+ body<Any> 要发送的数据, 如果是不允许有`body`的方式, 会被自动拼接到url上
+ cache<String> 是否缓存,
+ credentials<String/Boolean> 是否校验
+ signal<Object> 网络控制信号, 可用于中断请求
@ -67,10 +67,32 @@ f1('/get_list', {body: {page: 1}})
```js
fetch.BASE_URL = '//192.168.1.100'
fetch.__INIT__ = {headers: {token: 123456}}
fetch.__INIT__ = {headers: {token: 123456}} // 2.x 之后将废弃, 不推荐使用了
// 1.2.0开始支持注入
fetch.inject.request(function(conf) {
// 无需返回值, 但需要注意这是引用类型,不要对带个conf赋值
conf.headers.token = 123456
})
// 响应注入, 需要有返回值
fetch.inject.response(function(res) {
return res.json()
})
```
2. fetch.create([base_url][, options<Object>])
2. fetch.create([BASE_URL][, options<Object>])
> 创建一个新的fetch实例
```js
var another = fetch.create('//192.168.1.101')
// 新创建的实例, 也支持注入
another.inject.request(function(conf) {
conf.headers.token = 123456
})
another.inject.response(function(res) {
return res.json()
})
```

View File

@ -1,9 +1,11 @@
{
"name": "@bytedo/fetch",
"version": "1.1.3",
"version": "1.2.0",
"description": "全新的ajax封装。分2个版本, 一个基于XMLHttpRequest, 一个基于window.fetch",
"main": "dist/index.js",
"files": ["dist/*"],
"files": [
"dist/*"
],
"scripts": {
"start": "node ./build.js"
},
@ -11,7 +13,12 @@
"type": "git",
"url": "git+https://github.com/bytedo/fetch.git"
},
"keywords": ["fetch", "axois", "request", "ajax"],
"keywords": [
"fetch",
"axios",
"request",
"ajax"
],
"author": "yutent",
"license": "MIT",
"bugs": {

View File

@ -34,7 +34,7 @@ Promise.defer = function() {
}
class _Request {
constructor(url = '', options = {}, { BASE_URL, __INIT__ }) {
constructor(url = '', options = {}, { BASE_URL, __INIT__ }, owner) {
if (!url) {
throw new Error(ERRORS[10001])
}
@ -52,6 +52,7 @@ class _Request {
this.xhr = new XMLHttpRequest()
this.defer = Promise.defer()
this._owner = owner
this.options = {
headers: {
@ -73,7 +74,7 @@ class _Request {
control.abort()
}
var headers = this.options.headers
let headers = this.options.headers
if (__INIT__.headers) {
Object.assign(headers, __INIT__.headers)
@ -86,6 +87,10 @@ class _Request {
Object.assign(this.options, __INIT__, options, { url, headers })
if (owner._inject_req) {
owner._inject_req(this.options)
}
this.__next__()
return this.defer.promise
}
@ -155,8 +160,8 @@ class _Request {
let $a = document.createElement('a')
$a.href = options.url
crossDomain =
location.protocol !== $a.protocol || location.host !== $a.host
crossDomain = location.protocol !== $a.protocol || location.host !== $a.host
$a = null
} catch (err) {}
if (crossDomain) {
@ -176,8 +181,7 @@ class _Request {
options.url += (~options.url.indexOf('?') ? '&' : '?') + params
}
if (options.cache === 'no-store') {
options.url +=
(~options.url.indexOf('?') ? '&' : '?') + '_t_=' + Date.now()
options.url += (~options.url.indexOf('?') ? '&' : '?') + '_t_=' + Date.now()
}
} else {
if (!hasAttach) {
@ -197,16 +201,15 @@ class _Request {
// 6.1
this.xhr.onreadystatechange = ev => {
if (options.timeout > 0) {
options['time' + this.xhr.readyState] = ev.timeStamp
this['time' + this.xhr.readyState] = ev.timeStamp
if (this.xhr.readyState === 4) {
options.isTimeout = options.time4 - options.time1 > options.timeout
options.isTimeout = this.time4 - this.time1 > options.timeout
}
}
if (this.xhr.readyState !== 4) {
return
}
this.__dispatch__(options.isTimeout)
}
@ -285,6 +288,10 @@ class _Request {
var { body, status, statusText, headers } = result
var response = new Response(body, { status, statusText, headers })
if (this._owner._inject_res) {
response = this._owner._inject_res(response)
}
if (isSucc) {
this.defer.resolve(response)
} else {
@ -323,16 +330,36 @@ class _Request {
}
const _fetch = function (url, options) {
return new _Request(url, options, {
return new _Request(
url,
options,
{
BASE_URL: _fetch.BASE_URL,
__INIT__: _fetch.__INIT__ || Object.create(null)
})
},
_fetch
)
}
function inject(target) {
target.inject = {
request(callback) {
target._inject_req = callback
},
response(callback) {
target._inject_res = callback
}
}
}
_fetch.create = function (BASE_URL, __INIT__ = Object.create(null)) {
return function(url, options) {
return new _Request(url, options, { BASE_URL, __INIT__ })
var another = function (url, options) {
return new _Request(url, options, { BASE_URL, __INIT__ }, another)
}
inject(another)
return another
}
inject(_fetch)
export default _fetch

View File

@ -6,7 +6,7 @@
import { Format, toS } from './lib/format.js'
const NATIVE_FETCH = window.fetch
const nativeFetch = window.fetch
const NOBODY_METHODS = ['GET', 'HEAD']
const FORM_TYPES = {
form: 'application/x-www-form-urlencoded; charset=UTF-8',
@ -26,7 +26,7 @@ const ERRORS = {
}
class _Request {
constructor(url = '', options = {}, { BASE_URL, __INIT__ }) {
constructor(url = '', options = {}, { BASE_URL, __INIT__ }, owner) {
if (!url) {
throw new Error(ERRORS[10001])
}
@ -42,6 +42,8 @@ class _Request {
options.method = (options.method || 'get').toUpperCase()
this._owner = owner
this.options = {
headers: {
'X-Requested-With': 'XMLHttpRequest',
@ -58,7 +60,7 @@ class _Request {
options.signal = this.control.signal
}
var headers = this.options.headers
let headers = this.options.headers
if (__INIT__.headers) {
Object.assign(headers, __INIT__.headers)
@ -71,6 +73,10 @@ class _Request {
Object.assign(this.options, __INIT__, options, { url, headers })
if (owner._inject_req) {
owner._inject_req(this.options)
}
return this.__next__()
}
@ -133,8 +139,8 @@ class _Request {
let $a = document.createElement('a')
$a.href = options.url
crossDomain =
location.protocol !== $a.protocol || location.host !== $a.host
crossDomain = location.protocol !== $a.protocol || location.host !== $a.host
$a = null
} catch (err) {}
if (crossDomain && options.credentials === 'omit') {
@ -149,10 +155,6 @@ class _Request {
if (params) {
options.url += (~options.url.indexOf('?') ? '&' : '?') + params
}
if (options.cache === 'no-store') {
options.url +=
(~options.url.indexOf('?') ? '&' : '?') + '_t_=' + Date.now()
}
} else {
if (!hasAttach) {
if (~options.headers['content-type'].indexOf('json')) {
@ -176,18 +178,17 @@ class _Request {
var url = options.url
delete options.url
for (let k in options) {
if (
options[k] === null ||
options[k] === undefined ||
options[k] === ''
) {
if (options[k] === null || options[k] === undefined || options[k] === '') {
delete options[k]
}
}
return NATIVE_FETCH(url, options)
return nativeFetch(url, options)
.then(r => {
clearTimeout(this.timer)
var isSucc = r.status >= 200 && r.status < 400
let isSucc = r.status >= 200 && r.status < 400
if (this._owner._inject_res) {
r = this._owner._inject_res(r)
}
if (isSucc) {
return r
} else {
@ -210,16 +211,35 @@ class _Request {
}
const _fetch = function (url, options) {
return new _Request(url, options, {
return new _Request(
url,
options,
{
BASE_URL: _fetch.BASE_URL,
__INIT__: _fetch.__INIT__ || Object.create(null)
})
},
_fetch
)
}
function inject(target) {
target.inject = {
request(callback) {
target._inject_req = callback
},
response(callback) {
target._inject_res = callback
}
}
}
_fetch.create = function (BASE_URL, __INIT__ = Object.create(null)) {
return function(url, options) {
return new _Request(url, options, { BASE_URL, __INIT__ })
var another = function (url, options) {
return new _Request(url, options, { BASE_URL, __INIT__ }, another)
}
inject(another)
return another
}
inject(_fetch)
export default _fetch