需求是实现一个上传封面的功能。
为什么使用参数formdata?
一般当你想把复杂的数据从一个网页(文件,非ASCII编码的内容)发送到服务器,则必须使用multipart/form-data内容类型的form,例如:
1 2 3 4
| <form method="post" enctype="multipart/form-data" action="http://xxxx"> <input type="file" name="media"/> <input type="submit" value="upload"/> </form>
|
这就是我们平时做的上传文件的表单。
也许你想使用XMLHttpRequest发送文件。你想复制这种形式,这真的很难,因为你必须在JavaScript中创建multipart/form-data内容。
这时参数formdata就有用了:他重现在JavaScript中form的提交机制,XMLHttpRequest level 2(编者草案)增加了新的参数formdata接口的支持。 参数formdata对象提供了一种方法来轻松地构建一组键/值对表示表单字段及其值,然后可以使用XMLHttpRequest的send()方法以“multipart/form-data”的格式发送。
1 2 3 4 5 6 7 8 9
| <div class="y-topic-info" id="bg-set" style="background-image: url({{topic_info.pic_url}});"> <div class="y-topic-info-content" data-tid="{{topic_info['topic_id']}}"> <div class="change-bg-block"> <input type="file" name="change-bg" id="change-bg" class="upload-bg" data-sel="bg-file"> <a href="javascript:;" class="change-bg-btn">上传封面</a> </div> </div> <input type="hidden" id="uploadtoken" value="{{token}}"/> </div>
|
这里的token
字段是用户的一个信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| ;(function () { $('[data-sel=bg-file]').change(function(e){ var token = $('#uploadtoken').val() var file = document.getElementById('change-bg').files[0]
//创建一个空的FormData对象,然后再用append方法逐个添加键值对: var form = new FormData() form.append('file', file) form.append('token', token)
var xhr = new XMLHttpRequest() //上传 xhr.open("POST", "http://xxxx.com", true); //进度条 xhr.upload.addEventListener("progress", function(){ tool.showTip('上传中...',false) }, false);
//下载,内嵌ajax xhr.addEventListener("load", function(){ var postStr = JSON.parse(xhr.responseText).key; var outerSrc = 'xxxx/'+ postStr
$.ajax({ url : 'xxxx', type : 'POST', data : { 'icon' : postStr }, dataType: 'json', success : function(data) { document.getElementById('bg-set').style.backgroundImage="url("+outerSrc+")"; }, error : function(data) { alert('上传封面失败'); } });
}, false);
//错误信息 xhr.addEventListener("error", function(){ alert('上传封面失败'); }, false); //取消 xhr.addEventListener("abort", function(){ //... }, false);
//发送请求 xhr.send(form); }) })()
|
除了用原生的js实现ajax上传,还可以使用jquery的ajax上传:
1 2 3 4 5 6 7 8 9 10 11 12 13
| $.ajax({ type:'post', url:"http://xxxx", //上传格式为formData格式 data:formData, async: false, cache: false, contentType: false, processData: false,//好像不可缺! success:function(resultStr){ //... } });
|
总结
利用Formdata对象,我们可以使用原生js通过ajax实现异步上传图片,当然,现在已经有jquery的批量上传插件了,实现原理就是利用了Formdata。