模拟FormData创建表单请求
Posted ksyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟FormData创建表单请求相关的知识,希望对你有一定的参考价值。
class AppendStatus{
successed = false;
constructor(){
}
success(listenEvent){
this.successed = true;
if(listenEvent){
listenEvent.run();
}
}
getStatus(){
return !!this.successed
}
}
class ListenEvent{
callback;
appendStatusCache = [];
isRuned = false;
constructor(callback = ()=>{},appendStatusCache = []){
this.callback = callback;
this.appendStatusCache = appendStatusCache;
}
run(){
var ct = 0;
for(var i =0,l=this.appendStatusCache.length;i<l;i++){
if(this.appendStatusCache[i].getStatus()){
ct +=1;
};
};
if(ct >= this.appendStatusCache.length && !this.isRuned){
console.log("run success",ct);
this.callback();
this.isRuned = true;
}
}
}
class OurFormData {
// data;
rs;
callback;
appendStatusCache = [];
listenEvent;
constructor(rs) {
// this.data = data;
this.rs = rs;
// this.callback = callback;
}
append(k,v){
var appendStatus = new AppendStatus();
this.appendStatusCache.push(appendStatus);
let data_string = ‘
‘
this.segments = []
// this.rs = rs
this.status = 0
let resolve = ()=>{
appendStatus.success(this.listenEvent);
}
// let result = new Promise(res => resolve = res)
// let k, v
let getTag = v => ({}).toString.call(v)
// for ([k, v] of Object.entries(data)) {
// }
let tag = getTag(v)
console.log("append2",k,v,tag);
if (tag === ‘[object File]‘) {
// 单文件
let render = new FileReader()
render.readAsBinaryString(v);
// render.index = this.segments.length
var index;
render.onload = ({
target: {
result
}
}) => {
console.log("onload",k,v,tag);
this.segments[index] += `${result || ‘‘}
`;
// this.status--
// 所有异步全部完成
if (this.status === 0) {
resolve()
}
}
index = this.segments.push(
`------WebKitFormBoundary${this.rs||‘‘}
Content-Disposition: form-data; name="${k || ‘‘}"; filename="${v.name || ‘‘}"
Content-Type: "${v.type || ‘‘}"
`
)
// this.status++
} else if (tag === ‘[obejct Array]‘ && v.length > 0 && getTag(v[0]) === ‘[object File]‘) {
// 多文件
let file, render
for (file of v) {
render = new FileReader()
render.readAsBinaryString(file);
var index;
render.onload = ({
target: {
result
}
}) => {
this.segments[index] += `${result||‘‘}
`
// this.status--
// 所有异步全部完成
if (this.status === 0) {
resolve()
}
}
index = this.segments.push(
`------WebKitFormBoundary${this.rs||‘‘}
Content-Disposition: form-data; name="${k || ‘‘}"; filename="${v.name || ‘‘}"
Content-Type: "${v.type||‘‘}"
`
)
// this.status++
}
} else if(tag === ‘[object ArrayBuffer]‘){
console.log("[object ArrayBuffer]",v);
} else if (tag === ‘[object Array]‘) {
// 处理数组, age: [12, 14]
let $_
for ($_ of v) {
this.segments.push(
`------WebKitFormBoundary${this.rs||‘‘}
Content-Disposition: form-data; name="${k||‘‘}"
${$_||‘‘}
`
)
}
resolve()
} else {
// string and number
this.segments.push(
`------WebKitFormBoundary${this.rs||‘‘}
Content-Disposition: form-data; name="${k||‘‘}"
${v||‘‘}
`
)
resolve()
}
// if (this.status === 0) {
// resolve(this.handleResData(this.segments))
// }
// return result
}
handleResData(segments = this.segments) {
segments.unshift(`
`)
segments.push(`------WebKitFormBoundary${this.rs||‘‘}--`)
let data = segments.join(‘‘)
let bytes = data.length
console.log("handleResData",segments,bytes);
// let view = new Uint8Array(bytes)
// for (let i = 0; i < bytes; i++) {
// view[i] = data.charCodeAt(i) & 0xff
// }
let buffer = new ArrayBuffer(bytes)
let view = new DataView(buffer, 0)
let i
for (i = 0; i < bytes; i++) {
// & 0xff https://www.cnblogs.com/think-in-java/p/5527389.html
// view.setUint8(i, data.charCodeAt(i) & 0xff)
view.setUint8(i, data.codePointAt(i) & 0xff)
}
return view
}
ready(callback){
this.listenEvent = new ListenEvent(callback,this.appendStatusCache);
this.listenEvent.run();
}
}
return new Promise((res,rej) =>{
// let data = {
// name: ‘ajanuw‘,
// age: [1,2]
// }
// Object.assign(data, {
// file
// })
let rs = Date.now().toString(16)
let sendData = new OurFormData(rs)
try{
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function (e) {
console.info(reader.result); //ArrayBuffer {}
//经常会遇到的异常 Uncaught RangeError: byte length of Int16Array should be a multiple of 2
//var buf = new int16array(reader.result);
//console.info(buf);
//将 ArrayBufferView 转换成Blob
var buf = new Uint8Array(reader.result);
sendData.append("file",reader.result);
sendData.ready(()=>{
var formData = sendData.handleResData();
console.log("new beforeUpload222",sendData,formData)
fetch(this.$uploadUrl, {
method: ‘POST‘, // or ‘PUT‘
body: formData,
headers: new Headers({
// ‘Content-Type‘: ‘multipart/form-data‘
// ‘Content-Type‘: ‘application/json‘
"Content-Type":`multipart/form-data; boundary=----WebKitFormBoundary${rs||‘‘}`
})
}).then(res => res.json())
.catch(error => console.error(‘Error:‘, error))
.then(response => console.log(‘Success:‘, response));
})
}
}catch(e){
console.log("Error:",e)
}
rej();
})
以上是关于模拟FormData创建表单请求的主要内容,如果未能解决你的问题,请参考以下文章