优化表单解析, 支持多文件数组上传

master 2.1.6
yutent 2023-06-25 19:10:25 +08:00
parent 4d97503ee0
commit c286cdf2f2
5 changed files with 36 additions and 21 deletions

3
.gitignore vendored
View File

@ -1,6 +1,9 @@
*.min.js *.min.js
*.min.css *.min.css
demo.html
.httpserver
node_modules/ node_modules/
dist/ dist/

View File

@ -1,6 +1,6 @@
{ {
"name": "@bytedo/fetch", "name": "@bytedo/fetch",
"version": "2.1.5", "version": "2.1.6",
"description": "全新的ajax封装。分2个版本, 一个基于XMLHttpRequest, 一个基于window.fetch", "description": "全新的ajax封装。分2个版本, 一个基于XMLHttpRequest, 一个基于window.fetch",
"main": "dist/index.js", "main": "dist/index.js",
"files": [ "files": [

View File

@ -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 = {
@ -127,14 +127,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'
hasAttach = true )
break } else {
if (getType(options.body[k]) === 'File' || getType(options.body[k]) === 'Blob') {
hasAttach = true
break
}
} }
} }
// 有附件,则改为FormData // 有附件,则改为FormData
if (hasAttach) { if (hasAttach) {
if (noBody) { if (noBody) {
@ -289,13 +294,13 @@ class _Request {
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)

View File

@ -5,10 +5,12 @@
* *
*/ */
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)
}
/** /**
* 表单序列化 * 表单序列化
*/ */
@ -103,9 +105,10 @@ export const Format = {
if (/native code/.test(v)) { if (/native code/.test(v)) {
return return
} }
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)
} }

View File

@ -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']
@ -104,12 +104,16 @@ 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'
hasAttach = true )
break } else {
if (getType(options.body[k]) === 'File' || getType(options.body[k]) === 'Blob') {
hasAttach = true
break
}
} }
} }
// 有附件,则改为FormData // 有附件,则改为FormData
@ -175,12 +179,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)