Compare commits
6 Commits
Author | SHA1 | Date |
---|---|---|
|
f134e367b4 | |
|
763792d7f1 | |
|
5b403fb269 | |
|
33e4ffd659 | |
|
c286cdf2f2 | |
|
4d97503ee0 |
|
@ -1,6 +1,9 @@
|
||||||
*.min.js
|
*.min.js
|
||||||
*.min.css
|
*.min.css
|
||||||
|
|
||||||
|
demo.html
|
||||||
|
.httpserver
|
||||||
|
|
||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
dist/
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ f1('/get_list', {body: {page: 1}})
|
||||||
|
|
||||||
### APIs
|
### APIs
|
||||||
|
|
||||||
#### 1. fetch(url[, options<Object>])
|
#### 1. fetch(url[, options`<Object>`])
|
||||||
> 发起一个网络请求, options的参数如下。 同时支持配置公共域名, 公共参数。
|
> 发起一个网络请求, options的参数如下。 同时支持配置公共域名, 公共参数。
|
||||||
|
|
||||||
+ method`<String>` 默认GET, 可选GET/POST/PUT/DELETE...
|
+ method`<String>` 默认GET, 可选GET/POST/PUT/DELETE...
|
||||||
|
|
|
@ -55,7 +55,7 @@ f1('/get_list', {body: {page: 1}})
|
||||||
|
|
||||||
### APIs
|
### APIs
|
||||||
|
|
||||||
#### 1. fetch(url[, options<Object>])
|
#### 1. fetch(url[, options`<Object>`])
|
||||||
> 发起一个网络请求, options的参数如下。 同时支持配置公共域名, 公共参数。
|
> 发起一个网络请求, options的参数如下。 同时支持配置公共域名, 公共参数。
|
||||||
|
|
||||||
+ method`<String>` 默认GET, 可选GET/POST/PUT/DELETE...
|
+ method`<String>` 默认GET, 可选GET/POST/PUT/DELETE...
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "@bytedo/fetch",
|
"name": "@bytedo/fetch",
|
||||||
"version": "2.1.3",
|
"version": "2.1.9",
|
||||||
"description": "全新的ajax封装。分2个版本, 一个基于XMLHttpRequest, 一个基于window.fetch",
|
"description": "全新的ajax封装。分2个版本, 一个基于XMLHttpRequest, 一个基于window.fetch",
|
||||||
"main": "dist/index.js",
|
"main": "dist/next.js",
|
||||||
"files": [
|
"files": [
|
||||||
"dist/*"
|
"dist/*"
|
||||||
],
|
],
|
||||||
|
|
61
src/index.js
61
src/index.js
|
@ -4,7 +4,7 @@
|
||||||
* @date 2020/08/03 17:05:10
|
* @date 2020/08/03 17:05:10
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Format, toS } from './lib/format.js'
|
import { Format, getType } from './lib/format.js'
|
||||||
|
|
||||||
const NOBODY_METHODS = ['GET', 'HEAD']
|
const NOBODY_METHODS = ['GET', 'HEAD']
|
||||||
const FORM_TYPES = {
|
const FORM_TYPES = {
|
||||||
|
@ -25,7 +25,7 @@ const ERRORS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise.defer = function () {
|
Promise.defer = function () {
|
||||||
var _ = {}
|
let _ = {}
|
||||||
_.promise = new Promise(function (y, n) {
|
_.promise = new Promise(function (y, n) {
|
||||||
_.resolve = y
|
_.resolve = y
|
||||||
_.reject = n
|
_.reject = n
|
||||||
|
@ -66,7 +66,7 @@ class _Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.signal) {
|
if (!options.signal) {
|
||||||
var control = new AbortController()
|
let control = new AbortController()
|
||||||
options.signal = control.signal
|
options.signal = control.signal
|
||||||
}
|
}
|
||||||
this.defer.promise.abort = function () {
|
this.defer.promise.abort = function () {
|
||||||
|
@ -90,10 +90,10 @@ class _Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
__next__() {
|
__next__() {
|
||||||
var options = this.options
|
let options = this.options
|
||||||
var params = null
|
let params = null
|
||||||
var hasAttach = false // 是否有附件
|
let hasAttach = false // 是否有附件
|
||||||
var noBody = NOBODY_METHODS.includes(options.method)
|
let noBody = NOBODY_METHODS.includes(options.method)
|
||||||
|
|
||||||
/* ------------------------ 1»» 处理signal ---------------------- */
|
/* ------------------------ 1»» 处理signal ---------------------- */
|
||||||
options.signal.onabort = _ => {
|
options.signal.onabort = _ => {
|
||||||
|
@ -103,7 +103,7 @@ class _Request {
|
||||||
|
|
||||||
/* -------------------------- 2»» 请求的内容 --------------------- */
|
/* -------------------------- 2»» 请求的内容 --------------------- */
|
||||||
if (options.body) {
|
if (options.body) {
|
||||||
var type = typeof options.body
|
let type = typeof options.body
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'number':
|
case 'number':
|
||||||
case 'string':
|
case 'string':
|
||||||
|
@ -111,6 +111,11 @@ class _Request {
|
||||||
params = options.body
|
params = options.body
|
||||||
break
|
break
|
||||||
case 'object':
|
case 'object':
|
||||||
|
let _type = getType(options.body)
|
||||||
|
|
||||||
|
if (_type === 'ArrayBuffer' || _type === 'Uint8Array') {
|
||||||
|
break
|
||||||
|
}
|
||||||
// 解析表单DOM
|
// 解析表单DOM
|
||||||
if (options.body.nodeName === 'FORM') {
|
if (options.body.nodeName === 'FORM') {
|
||||||
options.method = options.body.method.toUpperCase() || 'POST'
|
options.method = options.body.method.toUpperCase() || 'POST'
|
||||||
|
@ -127,14 +132,19 @@ class _Request {
|
||||||
params = options.body
|
params = options.body
|
||||||
} else {
|
} else {
|
||||||
for (let k in options.body) {
|
for (let k in options.body) {
|
||||||
if (
|
if (Array.isArray(options.body[k]) || getType(options.body[k]) === 'FileList') {
|
||||||
toS.call(options.body[k]) === '[object File]' ||
|
options.body[k] = Array.from(options.body[k])
|
||||||
toS.call(options.body[k]) === '[object Blob]'
|
hasAttach = options.body[k].some(
|
||||||
) {
|
it => getType(it) === 'File' || getType(it) === 'Blob'
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
if (getType(options.body[k]) === 'File' || getType(options.body[k]) === 'Blob') {
|
||||||
hasAttach = true
|
hasAttach = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 有附件,则改为FormData
|
// 有附件,则改为FormData
|
||||||
if (hasAttach) {
|
if (hasAttach) {
|
||||||
if (noBody) {
|
if (noBody) {
|
||||||
|
@ -176,16 +186,17 @@ class _Request {
|
||||||
if (noBody) {
|
if (noBody) {
|
||||||
params = Format.param(params)
|
params = Format.param(params)
|
||||||
if (params) {
|
if (params) {
|
||||||
options.url += (~options.url.indexOf('?') ? '&' : '?') + params
|
options.url += (options.url.includes('?') ? '&' : '?') + params
|
||||||
}
|
}
|
||||||
if (options.cache === 'no-store') {
|
if (options.cache === 'no-store') {
|
||||||
options.url += (~options.url.indexOf('?') ? '&' : '?') + '_t_=' + Date.now()
|
options.url += (options.url.includes('?') ? '&' : '?') + '_t_=' + Date.now()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!hasAttach) {
|
if (options.body && !hasAttach) {
|
||||||
if (~options.headers['content-type'].indexOf('json')) {
|
if (options.headers['content-type'].includes('json')) {
|
||||||
params = JSON.stringify(params)
|
params = JSON.stringify(params)
|
||||||
} else {
|
}
|
||||||
|
if (options.headers['content-type'].includes('form')) {
|
||||||
params = Format.param(params)
|
params = Format.param(params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,19 +294,19 @@ class _Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
__success__(isSucc, result) {
|
__success__(isSucc, result) {
|
||||||
var { body, status, statusText, headers } = result
|
let { body, status, statusText, headers } = result
|
||||||
var response = new Response(body, { status, statusText, headers })
|
let response = new Response(body, { status, statusText, headers })
|
||||||
var _type
|
let _type
|
||||||
|
|
||||||
if (this._owner._inject_res) {
|
if (this._owner._inject_res) {
|
||||||
response = this._owner._inject_res(response)
|
response = this._owner._inject_res(response)
|
||||||
_type = toS.call(response)
|
_type = getType(it)(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSucc) {
|
if (isSucc) {
|
||||||
this.defer.resolve(response)
|
this.defer.resolve(response)
|
||||||
} else {
|
} else {
|
||||||
if (_type === '[object Promise]') {
|
if (_type === 'Promise') {
|
||||||
return response.then(_ => this.defer.reject(_)).catch(_ => this.defer.reject(_))
|
return response.then(_ => this.defer.reject(_)).catch(_ => this.defer.reject(_))
|
||||||
} else {
|
} else {
|
||||||
this.defer.reject(response)
|
this.defer.reject(response)
|
||||||
|
@ -307,7 +318,7 @@ class _Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
__cancel__(result) {
|
__cancel__(result) {
|
||||||
var response = new Response('', {
|
let response = new Response('', {
|
||||||
status: 0,
|
status: 0,
|
||||||
statusText: ERRORS[10100]
|
statusText: ERRORS[10100]
|
||||||
})
|
})
|
||||||
|
@ -320,7 +331,7 @@ class _Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
__timeout__(result) {
|
__timeout__(result) {
|
||||||
var response = new Response('', {
|
let response = new Response('', {
|
||||||
status: 504,
|
status: 504,
|
||||||
statusText: ERRORS[10504]
|
statusText: ERRORS[10504]
|
||||||
})
|
})
|
||||||
|
@ -348,7 +359,7 @@ const _fetch = function (url, options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetch.create = function () {
|
_fetch.create = function () {
|
||||||
var another = function (url, options) {
|
let another = function (url, options) {
|
||||||
return new _Request(url, options, another)
|
return new _Request(url, options, another)
|
||||||
}
|
}
|
||||||
inject(another)
|
inject(another)
|
||||||
|
|
|
@ -5,15 +5,17 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const toS = Object.prototype.toString
|
|
||||||
export const encode = encodeURIComponent
|
export const encode = encodeURIComponent
|
||||||
export const decode = decodeURIComponent
|
export const decode = decodeURIComponent
|
||||||
|
|
||||||
|
export function getType(val) {
|
||||||
|
return Object.prototype.toString.call(val).slice(8, -1)
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 表单序列化
|
* 表单序列化
|
||||||
*/
|
*/
|
||||||
function serialize(p, obj, query) {
|
function serialize(p, obj, query) {
|
||||||
var k
|
let k
|
||||||
if (Array.isArray(obj)) {
|
if (Array.isArray(obj)) {
|
||||||
obj.forEach(function (it, i) {
|
obj.forEach(function (it, i) {
|
||||||
k = p ? `${p}[${Array.isArray(it) ? i : ''}]` : i
|
k = p ? `${p}[${Array.isArray(it) ? i : ''}]` : i
|
||||||
|
@ -82,13 +84,17 @@ export const Format = {
|
||||||
mkFormData(data) {
|
mkFormData(data) {
|
||||||
let form = new FormData()
|
let form = new FormData()
|
||||||
for (let i in data) {
|
for (let i in data) {
|
||||||
let el = data[i]
|
let val = data[i]
|
||||||
if (Array.isArray(el)) {
|
if (val === void 0) {
|
||||||
el.forEach(function (it) {
|
val = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(val)) {
|
||||||
|
val.forEach(function (it) {
|
||||||
form.append(i + '[]', it)
|
form.append(i + '[]', it)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
form.append(i, data[i])
|
form.append(i, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return form
|
return form
|
||||||
|
@ -104,8 +110,14 @@ export const Format = {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (v === void 0) {
|
||||||
|
v = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
let _type = getType(v)
|
||||||
|
|
||||||
v = typeof v === 'function' ? v() : v
|
v = typeof v === 'function' ? v() : v
|
||||||
v = toS.call(v) === '[object File]' || toS.call(v) === '[object Blob]' ? v : encode(v)
|
v = _type === 'File' || _type === 'Blob' ? v : encode(v)
|
||||||
|
|
||||||
arr.push(encode(k) + '=' + v)
|
arr.push(encode(k) + '=' + v)
|
||||||
}
|
}
|
||||||
|
|
46
src/next.js
46
src/next.js
|
@ -4,7 +4,7 @@
|
||||||
* @date 2020/07/31 18:59:47
|
* @date 2020/07/31 18:59:47
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Format, toS } from './lib/format.js'
|
import { Format, getType } from './lib/format.js'
|
||||||
|
|
||||||
const nativeFetch = window.fetch
|
const nativeFetch = window.fetch
|
||||||
const NOBODY_METHODS = ['GET', 'HEAD']
|
const NOBODY_METHODS = ['GET', 'HEAD']
|
||||||
|
@ -75,19 +75,25 @@ class _Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
__next__() {
|
__next__() {
|
||||||
var options = this.options
|
let options = this.options
|
||||||
var hasAttach = false // 是否有附件
|
let hasAttach = false // 是否有附件
|
||||||
var noBody = NOBODY_METHODS.includes(options.method)
|
let noBody = NOBODY_METHODS.includes(options.method)
|
||||||
|
|
||||||
/* -------------------------- 1»» 请求的内容 --------------------- */
|
/* -------------------------- 1»» 请求的内容 --------------------- */
|
||||||
if (options.body) {
|
if (options.body) {
|
||||||
var type = typeof options.body
|
let type = typeof options.body
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'number':
|
case 'number':
|
||||||
case 'string':
|
case 'string':
|
||||||
this.__type__('text')
|
this.__type__('text')
|
||||||
break
|
break
|
||||||
case 'object':
|
case 'object':
|
||||||
|
let _type = getType(options.body)
|
||||||
|
|
||||||
|
if (_type === 'ArrayBuffer' || _type === 'Uint8Array') {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
// 解析表单DOM
|
// 解析表单DOM
|
||||||
if (options.body.nodeName === 'FORM') {
|
if (options.body.nodeName === 'FORM') {
|
||||||
options.method = options.body.method.toUpperCase() || 'POST'
|
options.method = options.body.method.toUpperCase() || 'POST'
|
||||||
|
@ -104,14 +110,18 @@ class _Request {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let k in options.body) {
|
for (let k in options.body) {
|
||||||
if (
|
if (Array.isArray(options.body[k]) || getType(options.body[k]) === 'FileList') {
|
||||||
toS.call(options.body[k]) === '[object File]' ||
|
options.body[k] = Array.from(options.body[k])
|
||||||
toS.call(options.body[k]) === '[object Blob]'
|
hasAttach = options.body[k].some(
|
||||||
) {
|
it => getType(it) === 'File' || getType(it) === 'Blob'
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
if (getType(options.body[k]) === 'File' || getType(options.body[k]) === 'Blob') {
|
||||||
hasAttach = true
|
hasAttach = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// 有附件,则改为FormData
|
// 有附件,则改为FormData
|
||||||
if (hasAttach) {
|
if (hasAttach) {
|
||||||
if (noBody) {
|
if (noBody) {
|
||||||
|
@ -138,14 +148,14 @@ class _Request {
|
||||||
if (noBody) {
|
if (noBody) {
|
||||||
let tmp = Format.param(options.body)
|
let tmp = Format.param(options.body)
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
options.url += (~options.url.indexOf('?') ? '&' : '?') + tmp
|
options.url += (options.url.includes('?') ? '&' : '?') + tmp
|
||||||
}
|
}
|
||||||
delete options.body
|
delete options.body
|
||||||
} else {
|
} else {
|
||||||
if (!hasAttach) {
|
if (options.body && !hasAttach) {
|
||||||
if (~options.headers['content-type'].indexOf('json')) {
|
if (options.headers['content-type'].includes('json')) {
|
||||||
options.body = JSON.stringify(options.body)
|
options.body = JSON.stringify(options.body)
|
||||||
} else {
|
} else if (options.headers['content-type'].includes('form')) {
|
||||||
options.body = Format.param(options.body)
|
options.body = Format.param(options.body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +171,7 @@ class _Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------- 5»» 构造请求 ------------------- */
|
/* ----------------- 5»» 构造请求 ------------------- */
|
||||||
var url = options.url
|
let url = options.url
|
||||||
delete options.url
|
delete options.url
|
||||||
for (let k in options) {
|
for (let k in options) {
|
||||||
if (options[k] === null || options[k] === undefined || options[k] === '') {
|
if (options[k] === null || options[k] === undefined || options[k] === '') {
|
||||||
|
@ -175,12 +185,12 @@ class _Request {
|
||||||
let _type
|
let _type
|
||||||
if (this._owner._inject_res) {
|
if (this._owner._inject_res) {
|
||||||
r = this._owner._inject_res(r)
|
r = this._owner._inject_res(r)
|
||||||
_type = toS.call(r)
|
_type = getType(r)
|
||||||
}
|
}
|
||||||
if (isSucc) {
|
if (isSucc) {
|
||||||
return r
|
return r
|
||||||
} else {
|
} else {
|
||||||
if (_type === '[object Promise]') {
|
if (_type === 'Promise') {
|
||||||
return r.then(_ => Promise.reject(_))
|
return r.then(_ => Promise.reject(_))
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject(r)
|
return Promise.reject(r)
|
||||||
|
@ -194,7 +204,7 @@ class _Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
abort() {
|
abort() {
|
||||||
this.control.abort()
|
this.control.abort(`Request timeout: ${~~(this.options.timeout / 1000)}s`)
|
||||||
}
|
}
|
||||||
|
|
||||||
__type__(type) {
|
__type__(type) {
|
||||||
|
@ -218,7 +228,7 @@ const _fetch = function (url, options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetch.create = function () {
|
_fetch.create = function () {
|
||||||
var another = function (url, options) {
|
let another = function (url, options) {
|
||||||
return new _Request(url, options, another)
|
return new _Request(url, options, another)
|
||||||
}
|
}
|
||||||
inject(another)
|
inject(another)
|
||||||
|
|
Loading…
Reference in New Issue