淺析FormData.append()的使用、FormData對象常用方法、如何使用FormData傳文件流傳json對象傳list數組、如何使用FormData傳多個文件、如何打印FormData對象的內容


  很早之前寫過一篇 FormData 對象方法的介紹,可以看這篇:HTML5 FormData 方法介紹以及實現文件上傳:上傳文件實例、FormData 對象方法介紹

一、FormData.append()

  FormData 接口的 append() 方法 會添加一個新值到 FormData 對象內的一個已存在的鍵中,如果鍵不存在則會添加該鍵。

  FormData.set 和 append() 的區別在於,如果指定的鍵已經存在, FormData.set 會使用新值覆蓋已有的值,而 append() 會把新值添加到已有值集合的后面。

1、語法:這個方法有兩個版本:一個有兩個參數的版本和一個有三個參數的版本。

formData.append(name, value);
formData.append(name, value, filename);

2、參數:

(1)name:字段名稱,也就是 key。value中包含的數據對應的表單名稱。

(2)value:表單的值。可以是USVString 或 Blob (包括子類型,如 File)。

(3)filename: 可選。傳給服務器的文件名稱 (一個 USVString),當一個 Blob 或 File 被作為第二個參數的時候, Blob 對象的默認文件名是 "blob"。 File 對象的默認文件名是該文件的名稱。(注意: 如果你指定一個 Blob 作為數據添加到 FormData 對象中, 文件名會被放在 "Content-Disposition" 頭部(常常會根據瀏覽器變化而變化)傳給服務器。)

  第三個參數 filename 之前確實沒用過,得注意一下,今天也是看到這個第 3 個參數,所以決定研究一下。

二、FormData 常用方法

1、創建 FormData 對象

// 1、創建一個空對象
var formData = new FormData(); // 2、使用已有表單來初始化對象 //表單示例
<form id="myForm" action="" method="post">
    <input type="text" name="name">名字 <input type="password" name="psw">密碼 <input type="submit" value="提交">
</form>

//方法示例 // 獲取頁面已有的一個form表單
var form = document.getElementById("myForm"); // 用表單來初始化
var formData = new FormData(form); // 我們可以根據name來訪問表單中的字段
var name = formData.get("name"); // 獲取名字
var psw = formData.get("psw"); // 獲取密碼 // 當然也可以在此基礎上,添加其他數據
formData.append("token","kshdfiwi3rh");

2、操作方法

// 1、獲取值:通過get(key)/getAll(key)來獲取對應的value
formData.get("name"); // 獲取key為name的第一個值
formData.getAll("name"); // 返回一個數組,獲取key為name的所有值 // 2、添加數據:通過append(key, value)來添加數據 // 如果指定的key不存在則會新增一條數據,如果key存在,則添加到數據的末尾
formData.append("k1", "v1"); formData.append("k1", "v2"); formData.get("k1"); // "v1"
formData.getAll("k1"); // ["v1","v2","v3"] // 3、設置修改數據:set(key, value)來設置修改數據 // 如果指定的key不存在則會新增一條,如果存在,則會修改對應的value值
formData.append("k1", "v1"); formData.set("k1", "1"); formData.getAll("k1"); // ["1"] // 4、判斷是否存在對應數據:has(key)來判斷是否對應的key值
formData.has("k1"); // true // 5、刪除數據
formData.delete("k1");

三、formData.append() 遇到的問題

1、formData使用append追加后console仍為空的問題

formData.append('image_url', files[0]); console.log(formData)

  解決:需要用 formData.get("鍵") 的方法獲取值。

let formData = new FormData(); formData.append('image_url', files[0]); console.log(formData.get('image_url'))

2、formData.append("files",filesArray) 添加文件無效的問題

  選擇多個文件一起上傳,就參考選用了FormData實例通過append方法添加文件並發送,原代碼是這么寫的:

let formData = new FormData(); formData.append("files",this.createOperation.fileList);

  這種以數組形式append的方式具有以下特征:

(1)append之后,調試發現formData為空,查閱資料得知formData需要使用FormData.get,FormData.getAll,FormData.keys等方法訪問其內部的鍵值對。

(2)瀏覽器network調試面板中可看到發送的files參數為[object file]形式,而正確的形式應該是[binary]

  解決方案:分多次向formData中同一個鍵名下添加一個文件即可。

this.createOperation.fileList.map(element => { formData.append("files", element); });

四、使用 FormData 傳文件流,傳 json 數組對象(重點)

  關於 FormData.append() 的參數,這里要注意下 value 字段,如果你要填入的是一個對象,會將它轉換成字符串,也就是最后傳給后台的都是 [object object],這樣后台當然是無法解析的。下邊舉個例子,大家就明白了

var json=[   {'name':'小明','age':15,'skills':['抽煙','喝酒','燙頭'],'family':{'father':'大明','mohter':'小紅'}},   {'name':'胖虎','age':17,'skills':['打架','打架','還是打架'],'family':{'father':'佐藤','mohter':'愛田'}}, ]

  首先我們先試一下,把小明的family對象傳給后台。

var data=new FormData() data.append('family',json[0].family)

  結果被解析成了object object,有人該說了,你把它用 JSON.stringify 序列化之后不就行了,然后后端配合,再解碼成json,對,這樣確實行,但不要忘了,咱們還是需要傳文件流的,文件流被序列化之后會被轉化成一個空對象,這樣后台就無法識別。由於時間原因,這里就不演示反面案例了。這里我們要用兩個語法:

1、a['b'] 等於 a.b

2、c[0] 取得是c數組的第一項

  正確方法:
var data=new FormData() for(var i=0,len=json.length;i<len;i++){ data.append('json['+i+'][name]',json[i].name) data.append('json['+i+'][age]',json[i].age) data.append('json['+i+'][family][father]',json[i].family.father) data.append('json['+i+'][family][mother]',json[i].family.mohter) for(var j=0,len2=json[i].skills.length;j<len2;j++){ data.append('skills['+i+']['+j+']',json[i].skills[j]) } } $.ajax({ url:'demo.php', type: "Post", dataType: "json", cache: false,//上傳文件無需緩存
         processData: false,//用於對data參數進行序列化處理 這里必須false
         contentType: false, //必須
 data:data, success:function (res) { console.log(res); }, error:function (error) { console.log(error); } })

  之后,我們再給小明和胖虎每人上傳一張個人寫真照(利用input file,文件流),這里我們利用input上傳時的file對象,附上代碼:

<input type="file" id="upload"> $('#upload').on('change',function (e) {   var file = e.target.files[0];   console.log(file);   data.append('json[0][image]',file) })

  這里需要注意的是:如果是繼續上傳照片,還是在這個字段 'json[0][image]' 里去 append file。如第 3 講第 2 個問題。

  這個 file 對象是一個含有二進制文件,這個對象如果直接序列化,會被轉化為一個空對象,后台無法識別。所以如果有特殊的文件之類的,那就無法使用 JSON.stringify 序列化去傳參數了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM