以前在Vue的项目里面用到过文件上传,封装好的组件用起来比较顺手,查询Element-UI文档,十八般武器样样都有,一顿操做猛如虎,一看……跑偏了(⊙o⊙)…,个人意思就是用框架实现比较简单,可是若是用jQuery的话,对原理可能会更了解一些,有须要的一块儿看下吧~javascript
由于HTTP提供的是基于文本的通讯协议,而上传文件传输的是二进制数据,因此须要使用multipart/form-data
编码格式,其HTTP消息体格式以下:html
------WebKitFormBoundaryb0GZcypmEqOvNHIY Content-Deiposition: form-data; name="file"; filename="icon.png" Content-Type: image/png ------WebKitFormBoundaryb0GZcypmEqOvNHIY
multipart/form-data
的请求头包含一个特殊的头信息Content-Type,其值为multipart/form-data,另外须要规定一个内容分割boundary用于分割请求体中多个不一样的内容:前端
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryb0GZcypmEqOvNHIY
java
<form> <input type="file" id="uplfile" name="uplfile"/> <button type="button" id="uplfileBtn">上传</button> </form>
type="file"
的input有一个叫files
的DOM属性,能够获取到所选的文件列表(Array),数组中每个对象都是file类型,jquery
var files = $("#uplfile").prop('files');
新版本的XMLHttpRequest对象可使用FormData
对象管理表单数据,能够帮咱们进行二进制文件的multipart/form-data编码,以下:web
$("#uplfileBtn").click(function(){ var files = $("#uplfile").prop('files'); var data = new FormData(); data.append('file', files[0]); //参数名:file $.ajax({ url: URL, type: 'POST', data: data, cache: false, //禁止浏览器对该URL的缓存 contentType: false, processData: false, success: function(){ //后续操做 } }); });
contentType
:jQuery中contentType默认为application/x-www-form-urlencoded
,所以传入的data会被转为默认的HTTP编码,这里咱们不须要这种转换,设置为false。ajax
processData
:jQuery会将传入的data对象转为字符串来发送HTTP请求,这里咱们的data已是FormData对象处理好的multipart/form-data编码,因此不须要转换,设置为false。数组
一般在web前端须要下载服务端文件,都是经过指定<a>
标签的href属性访问服务端URL来下载保存文件的,也能够在js中:浏览器
document.location.href = Url + '?fileName=' + value;
上面这种方法用的是HTTP的GET请求,只能经过URL传参,在相对复杂的场景中(须要传多个参数在服务端动态下载指定文件),即参数比较多的时候,咱们想要可以经过ajaxPOST
方式来传递参数。缓存
可是用ajax请求的数据只能存放在JavaScript的内存中,能够经过js读取,没法保存到硬盘,由于JavaScript自己没法直接和硬盘交互。那么有什么方法能够实现呢?一贯方法总比困难多,咱们能够经过模拟Form表单的提交来实现POST请求下载文件,以下:
<form id="myform" action="http://blog.kwin.wang/test/xxx.do" method="post"> <input type="hidden" name="type" value="trade"/> <input type="hidden" name="time" value="20180818"/> <input type="hidden" name="fileName" value="a.png"/> </form>
主动提交Form表单:
$("#myform")[0].submit();
以上就是本文所有内容了,欢迎有兴趣的朋友评论区留言交流~