天天看點

formdata和PHP實作檔案上傳,jQuery用FormData實作檔案上傳的方法

前言

我們引入jQuery來進行異步上傳可以獲得更好的使用者體驗。 一方面,在JavaScript中進行異步操作比表單更加靈活; 另一方面,異步上傳也避免了上傳大檔案時的頁面長時間卡死。

HTML

一個type=file的就可以讓使用者來浏覽并選擇檔案, 一般會把輸入控件放到一個

中,下面的一個簡單的表單:

儲存

但為什麼我隻能選擇一個檔案??給添加一個multiple屬性就可以多選了!

擷取檔案清單

上述的将會擁有一個叫files的DOM屬性,包含了所選的檔案清單(Array)。$('button').click(function(){

var $input = $('#avatar');

// 相當于: $input[0].files, $input.get(0).files

var files = $input.prop('files');

console.log(files);

});

這個Array中的每一項都是一個File對象,它有下面幾個主要屬性:

name: 檔案名,隻讀字元串,不包含任何路徑資訊.

size: 檔案大小,機關為位元組,隻讀的64位整數.

type: MIME類型,隻讀字元串,如果類型未知,則傳回空字元串.

詳情可以參考:https://developer.mozilla.org/zh-CN/docs/Using_files_from_web_applications

multipart/form-data

上傳檔案比較特殊,其内容是二進制資料,而HTTP提供的是基于文本的通信協定。 這時需要采用multipart/form-data編碼的HTTP表單。

其HTTP消息體格式如下所示:------WebKitFormBoundaryrGKCBY7qhFd3TrwA

Content-Disposition: form-data; name="title"

harttle

------WebKitFormBoundaryrGKCBY7qhFd3TrwA

Content-Disposition: form-data; name="avatar"; filename="harttle.png"

Content-Type: image/png

... content of harttle.png ...

------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

每個字段由一段boundary string來分隔,浏覽器保證該boundary string不與内容重複, 因而multipart/form-data能夠成功編碼二進制資料。

jQuery上傳檔案

這是XMLHttpRequest Level 2提供的FormData對象可以幫助我們進行二進制檔案的 multipart/form-data編碼:$('button').click(function(){

var files = $('#avatar').prop('files');

var data = new FormData();

data.append('avatar', files[0]);

$.ajax({

url: '/api/upload',

type: 'POST',

data: data,

cache: false,

processData: false,

contentType: false

});

});

url, type, data想必做前端的都很熟悉了,介紹其餘三個參數:

cache

cache設為false可以禁止浏覽器對該URL(以及對應的HTTP方法)的緩存。 jQuery通過為URL添加一個備援參數來實作。

該方法隻對GET和HEAD起作用,然而IE8會緩存之前的GET結果來響應POST請求。 這裡設定cache: false是為了相容IE8。

參考:http://api.jquery.com/jquery.ajax/

contentType

jQuery中content-type預設值為application/x-www-form-urlencoded, 是以傳給data參數的對象會預設被轉換為query string(見HTTP 表單編碼 enctype)。

我們不需要jQuery做這個轉換,否則會破壞掉multipart/form-data的編碼格式。 是以設定contentType: false來禁止jQuery的轉換操作。

processData

jQuery會将data對象轉換為字元串來發送HTTP請求,預設情況下會用 application/x-www-form-urlencoded編碼來進行轉換。 我們設定contentType: false後該轉換會失敗,是以設定processData: false來禁止該轉換過程。

我們給的data就是已經用FormData編碼好的資料,不需要jQuery進行字元串轉換。

相容性與其他選擇

本文介紹的jQuery檔案上傳方式依賴于FormData對象, 這是XMLHttpRequest Level 2接口, 需要 IE 10+, Firefox 4.0+, Chrome 7+, Safari 5+, Opera 12+

這意味着對于低版本浏覽器隻能使用直接送出檔案表單的形式, 但送出大檔案表單頁面會長時間不響應,如果希望在低版本浏覽器中解決該問題, 就隻能使用别的方式來實作了,比如很多支援多檔案和上傳進度的Flash插件。

本文原創釋出php中文網,轉載請注明出處,感謝您的尊重!