Web文件上传方法总结大全
文件上傳在WEB開(kāi)發(fā)中應(yīng)用很廣泛,我們經(jīng)常發(fā)微博、發(fā)微信朋友圈都用到了圖片上傳功能。
文件上傳是指將本地圖片、視頻、音頻等文件上傳到服務(wù)器上,可以供其他用戶瀏覽或下載的過(guò)程。
今天我給大家聊聊常見(jiàn)的文件(圖片)上傳的方式和要點(diǎn)處理。
表單上傳
這是傳統(tǒng)的form表單上傳,使用form表單的input[type=”file”]控件,可以打開(kāi)系統(tǒng)的文件選擇對(duì)話框,從而達(dá)到選擇文件并上傳的目的,它的好處是多瀏覽器兼容,它是web開(kāi)發(fā)者最常用的一種文件上傳方式。
表單的代碼如下:
<form method="post" action="http://uploadUrl" enctype="multipart/form-data"><input name="file" type="file" accept="image/gif,image.jpg" /><input name="token" type="hidden" /><input type="submit" value="提交" /> </form>?
以下是表單上傳幾個(gè)關(guān)鍵點(diǎn):
- method=”post”: 采用post方式提交數(shù)據(jù)
- enctype=”multipart/form- data”:采用multipart格式上傳文件,此時(shí)request頭會(huì)顯示 Content-Type:multipart/form-data; boundary=—-WebKitFormBoundaryzr34cwJ67R95KQC9
- action:標(biāo)明上傳的服務(wù)端處理地址
- type=”file”:使用input的file控件上傳
- 如果是多文件批量上傳,可以將input[type=”file”]的name屬性設(shè)置為如:name=”file[]”
- accept屬性是HTML5的新屬性,它規(guī)定了可通過(guò)文件上傳提交的文件類型
- 上傳的觸發(fā)事件可以是:input[type=”file”]的onChange觸發(fā),也可以由一個(gè)獨(dú)立的按鈕的onClick使整個(gè)表單提交,此時(shí)還可以用input[type=”hidden”]帶一些其它的參數(shù),比如Token來(lái)源驗(yàn)證等等。
Ajax無(wú)刷新上傳
Ajax無(wú)刷新上傳的方式,本質(zhì)上與表單上傳無(wú)異,只是把表單里的內(nèi)容提出來(lái)采用ajax提交,并且由前端決定請(qǐng)求結(jié)果回傳后的展示結(jié)果,不用像直接表單上傳那樣刷新和跳轉(zhuǎn)頁(yè)面。在這里,我們采用jQuery來(lái)作為操作DOM和創(chuàng)建ajax提交的js基礎(chǔ)庫(kù)。
html代碼片段如下:
<form><input id="file" name="file" type="file" /><input id="token" name="token" type="hidden" /> </form>javascript代碼片段如下:
$("#file").on("change", function(){var formData = new FormData();formData.append("file", $("#file")[0].files);formData.append("token", $("#token").val());$.ajax({url: "http://uploadUrl",type: "POST",data: formData,processData: false,contentType: false,success: function(response){// 根據(jù)返回結(jié)果指定界面操作}}); });我們使用了file控件的change來(lái)觸發(fā)上傳事件,當(dāng)然你也可以使用某個(gè)按鈕來(lái)觸發(fā)表單提交。提交數(shù)據(jù)時(shí),我 用到了FormData對(duì)象來(lái)發(fā)送二進(jìn)制文件,FormData構(gòu)造函數(shù)提供的append()方法,除了直接添加二進(jìn)制文件還可以附帶一些其它的參數(shù), 作為XMLHttpRequest實(shí)例的參數(shù)提交給服務(wù)端。
使用jQuery提供的ajax方法來(lái)發(fā)送二進(jìn)制文件,還需要附加兩個(gè)參數(shù):
- processData: false // 不要對(duì)data參數(shù)進(jìn)行序列化處理,默認(rèn)為true
- contentType: false // 不要設(shè)置Content-Type請(qǐng)求頭,因?yàn)槲募?shù)據(jù)是以 multipart/form-data 來(lái)編碼
Flash上傳
很 多時(shí)候上傳的需求要求顯示上傳進(jìn)度、中斷上傳過(guò)程、大文件分片上傳等等,這時(shí)傳統(tǒng)的表單上傳很難實(shí)現(xiàn)這些功能,于是產(chǎn)生了使用Flash上傳的方式,它采 用Flash作為一個(gè)中間代理層,代替客戶端跟服務(wù)端通信,此外,它也對(duì)客戶端的文件選擇方面擁有更多的控制權(quán),比input[type=”file”] 要大得多。
在這里我使用了jQuery封裝好的uploadify插件來(lái)進(jìn)行演示,一般這類插件都自帶了上傳用的Flash文件,因?yàn)楦?wù)端回傳的數(shù)據(jù)和展示跟客戶端的交互,都是Flash文件的接口跟插件來(lái)對(duì)接的。
<div id="file_upload"></div>
html部分很簡(jiǎn)單,預(yù)留一個(gè)hook后,插件會(huì)在這個(gè)節(jié)點(diǎn)內(nèi)部創(chuàng)建Flash的object,并且還附帶創(chuàng)建了上傳進(jìn)度、取消控件和多文件隊(duì)列展示等界面。
$(function() {$("#file_upload").uploadify({auto: true,method: "Post",width: 120,height: 30,swf: './uploadify.swf',uploader: 'http://uploadUrl',formData: {token: $("#token").val()},fileObjName: "file",onUploadSuccess: function(file, data, response){// 根據(jù)返回結(jié)果指定界面操作}}); });關(guān)于jQuery.uploadify可以訪問(wèn)了解:http://www.uploadify.com/documentation/。值得注意的是flash并不適合手機(jī)端應(yīng)用,更好的解決方案是使用flash+html5來(lái)解決平臺(tái)的兼容性問(wèn)題。
截圖粘貼上傳
我們發(fā)現(xiàn)現(xiàn)在有好多上傳應(yīng)用已經(jīng)提供了截圖粘貼上傳功能,如WebUploader,它就支持QQ截圖然后粘貼上傳。
首先,截圖粘貼上傳的核心思想是,監(jiān)聽(tīng)粘貼事件,然后獲取剪切板中的數(shù)據(jù),如果是一張圖片,則觸發(fā)上傳事件。
代碼片段如下:
$("textarea").on("paste", function(e){e.stopPropagation();var self = this;var clipboardData = e.originalEvent.clipboardData;if (clipboardData.items.length <= 0) {return;}var file = clipboardData.items[0].getAsFile();if (!file) {return;}var formData = new FormData();formData.append("file", file);formData.append("token", $("#token").val());$.ajax({url: "http://uploadUrl",type: "POST",data: formData,}).done(function(response) {// 根據(jù)返回結(jié)果指定界面操作});e.preventDefault(); });從上面代碼可以看出,上傳的過(guò)程都是一樣的,主要是獲取文件的方式。 當(dāng)進(jìn)行粘貼(右鍵paste/ctrl+v)操作時(shí),觸發(fā)剪貼板事件’paste’,從系統(tǒng)剪切板獲取內(nèi)容,而系統(tǒng)剪切板的數(shù)據(jù)在不同瀏覽器保存在不同的位置:
- IE內(nèi)核:windows.clipboardData
- 其它:e.originalEvent.clipboardData
拖拽上傳
拖拽上傳的方式,支持的瀏覽器比較少,因?yàn)樗玫搅薍TML5的兩個(gè)新的屬性(API)一個(gè)是Drag and Drop,一個(gè)是File API。
上傳域監(jiān)聽(tīng)拖拽的三個(gè)事件:dragEnter、dragOver和drop,分別對(duì)應(yīng)拖拽至、拖拽時(shí)和釋放三個(gè)操作的處理機(jī)制,當(dāng)然你也可以監(jiān)聽(tīng)dragLeave事件。
HTML5的File API提供了一個(gè)FileList的接口,它可以通過(guò)拖拽事件的e.dataTransfer.files來(lái)傳遞的文件信息,獲取本地文件列表信息。
File API在HTML5規(guī)范中只是草案,在 W3C 草案中,File 對(duì)象只包含文件名、文件類型和文件大小等只讀屬性。但部分瀏覽器在草案之外提供了一個(gè)名為 FileReader 的對(duì)象,用以讀取文件內(nèi)容,并且可以監(jiān)控讀取狀態(tài),它提供的方法有: “readAsBinaryString” ,”readAsDataURL” ,”readAsText” ,”abort” 等。
代碼片段如下:
// dragenter$("#textarea").on("dragenter", function(e){e.preventDefault(); });// dragover$("#textarea").on("dragover", function(e){e.preventDefault(); });// drop$("#textarea").on("drop", function(e){e.stopPropagation();e.preventDefault();var files = e.originalEvent.dataTransfer.files;_.each(files, function(file) {if (!/^image*/.test(file.type)) {return;}var fileReader = new FileReader();fileReader.onload = function() {//uploadFile(file);};fileReader.readAsDataURL(file);}); });拖拽上傳過(guò)程中的幾個(gè)關(guān)鍵點(diǎn):
- 在drop事件觸發(fā)后通過(guò)e.dataTransfer.files獲取拖拽文件列表,在jQuery中是e.originalEvent.dataTransfer.files
- 拖拽上傳僅支持圖片,文件對(duì)象中file.type標(biāo)識(shí)了文件類型。
- 由于可能是多圖拖拽,所以可以遍歷圖片上傳,這里用了Underscore的each方法。
- 這里用readAsDataURL讀取文件內(nèi)容為二進(jìn)制文件,你還可以將其轉(zhuǎn)換為Base64方式上傳,只是http協(xié)議里面存在對(duì)非二進(jìn)制數(shù)據(jù)的上傳大小限制為2M。
- 上傳的過(guò)程跟前面的方式相同,即:創(chuàng)建FormData對(duì)象并發(fā)起Ajax請(qǐng)求。
拍照上傳
拍照上傳可以是PC上的攝像頭拍照上傳也可以是手機(jī)等移動(dòng)設(shè)備的拍照上傳。手機(jī)上的拍照上傳最常見(jiàn)就是我們使用微信發(fā)照片了。
手機(jī)實(shí)現(xiàn)拍照上傳的代碼:
<input type=file accept="image/*">
?
<input type=file accept="video/*">
ios 有拍照、錄像、選取本地圖片功能,部分android只有選取本地圖片功能。
上傳與安全
上傳文件時(shí)必須做好文件的安全性,除了前端必要的驗(yàn)證,如文件類型、后綴、大小等驗(yàn)證,重要的還是要在后臺(tái)做安全策略。
這里我列舉幾個(gè)注意點(diǎn):
- 后臺(tái)需要進(jìn)行文件類型、大小、來(lái)源等驗(yàn)證
- 定義一個(gè).htaccess文件,只允許訪問(wèn)指定擴(kuò)展名的文件。
- 將上傳后的文件生成一個(gè)隨機(jī)的文件名,并且加上此前生成的文件擴(kuò)展名。
- 設(shè)置上傳目錄執(zhí)行權(quán)限,避免不懷好意的人繞過(guò)如圖片擴(kuò)展名進(jìn)行惡意攻擊,拒絕腳本執(zhí)行的可能性。
?
總結(jié)
以上是生活随笔為你收集整理的Web文件上传方法总结大全的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: web 应用常见安全漏洞一览
- 下一篇: 网页页面颜色