fetch/src/lib/format.js

120 lines
2.7 KiB
JavaScript

/**
*
* @authors yutent (yutent.io@gmail.com)
* @date 2016-11-26 16:35:45
*
*/
export const toS = Object.prototype.toString
export const encode = encodeURIComponent
export const decode = decodeURIComponent
/**
* 表单序列化
*/
function serialize(p, obj, query) {
var k
if (Array.isArray(obj)) {
obj.forEach(function (it, i) {
k = p ? `${p}[${Array.isArray(it) ? i : ''}]` : i
if (typeof it === 'object') {
serialize(k, it, query)
} else {
query(k, it)
}
})
} else {
for (let i in obj) {
k = p ? `${p}[${i}]` : i
if (typeof obj[i] === 'object') {
serialize(k, obj[i], query)
} else {
query(k, obj[i])
}
}
}
}
export const Format = {
parseForm(form) {
let data = {}
let hasAttach = false
for (let i = 0, field; (field = form.elements[i++]); ) {
switch (field.type) {
case 'select-one':
case 'select-multiple':
if (field.name.length && !field.disabled) {
for (let j = 0, opt; (opt = field.options[j++]); ) {
if (opt.selected) {
data[field.name] = opt.value || opt.text
}
}
}
break
case 'file':
if (field.name.length && !field.disabled) {
data[field.name] = field.files[0]
hasAttach = true
}
break
case undefined:
case 'submit':
case 'reset':
case 'button':
break //按钮啥的, 直接忽略
case 'radio':
case 'checkbox':
// 只处理选中的
if (!field.checked) break
default:
if (field.name.length && !field.disabled) {
data[field.name] = field.value
}
}
}
// 如果有附件, 改为FormData
if (hasAttach) {
return this.mkFormData(data)
} else {
return data
}
},
mkFormData(data) {
let form = new FormData()
for (let i in data) {
let el = data[i]
if (Array.isArray(el)) {
el.forEach(function (it) {
form.append(i + '[]', it)
})
} else {
form.append(i, data[i])
}
}
return form
},
param(obj) {
if (!obj || typeof obj === 'string' || typeof obj === 'number') {
return obj
}
let arr = []
let query = function (k, v) {
if (/native code/.test(v)) {
return
}
v = typeof v === 'function' ? v() : v
v = toS.call(v) === '[object File]' || toS.call(v) === '[object Blob]' ? v : encode(v)
arr.push(encode(k) + '=' + v)
}
if (typeof obj === 'object') {
serialize('', obj, query)
}
return arr.join('&')
}
}
全新的ajax封装。分2个版本, 一个基于XMLHttpRequest, 一个基于window.fetch
JavaScript 100%