let formdata=new FormData();
formdata.append('file',file)'//文件file添加到FormData中
formdata.append('test','test123')
for(let info of formdata){
console.log(info)
}
当使用FormData上传文件的时候,不需要修改请求头,浏览器会自动修改
这里做个说明
//在axios源码中对xhr的封装中,会对data的类型做判断,如果data是FormData类型,
那就删除掉请求头中的content-type
原因如下:
- 传文件的时候,请求头的content-type应该是'multipart/form-data',而不是'application/x-www-form-urlencode' 二者都可以传FormData格式的数据。但是form-urlencode只是针对于键值对类型的formdata,如果包含了文件 还是要用multipart/form-data
- 不过值得注意的是,不要在传文件的时候,手动修改content-type,而是不要设置,让浏览器自行判断 这里可以看下上传文件的headers与payload
payload中用------WebKit 分隔符把formdata的字段隔开了,
header中,没有手动添加Content-Type,是浏览器自动识别添加的,并且还有个bounary,也就是payload中的分隔符
- 后台拿到了传过去的formdata需要解析,但是内容被分隔符分隔开了,而分隔符是不确定的字符。所以后台通过header中的boundary,对formdata进行解析
- 浏览器会自动给formdata添加分隔符,这个分隔符是浏览器随机生成的,所以传文件的时候,要记得不要写Content-Type,让浏览器自己生成Content-Type
读取文件
let fr=new FileReader( ) ;
let file=this.files[ 0 ];
fr.readAsArrayBuffer( file ) --返回一个buffer
fr.readAsBinaryString( file )--返回一个二进制数据,适用于多媒体文件
fr.readAsDataURL( file )--可以当做路径使用的数据,base64字符串,适用于图片的src,比如上传预览
fr的结果在onload事件中获取,通过fr.result或者e.target.result
fr.onload=function(e){
console.log(fr.result);
console.log(e.target.result)
}
这里说下DataUrl
DataUrl直接存储图片base64编码后的数据,往往是比较长的,所以当现实大图片的时候,可以使用Blob URl(URL.createObjectURL)
Blob URL可以直接使用create出来的blob url使用请求获取源数据。不过只能在当前应用内部使用。
//这里对比下原生form表单提交数据的方式
let submitForm = document.createElement("FORM");let id_name = 'file-created-form'submitForm.id = id_name
document.body.appendChild(submitForm);submitForm.method = "POST";submitForm.className = "myForm"submitForm.action = '/api/...';let newElement;for (var key in form_data) { var val = form_data[key]; newElement = document.createElement("input"); newElement.setAttribute("name", key); newElement.setAttribute("type", "hidden"); if (val) { if(typeof val === 'object' ) { val = JSON.stringify(val) } newElement.setAttribute("value", val); } submitForm.appendChild(newElement); }submitForm.submit();document.getElementById(id_name).parentNode.removeChild(submitForm);