解密”Ajax”技術:輕鬆應對文字和檔案一同上傳的挑戰

概述_ ajax 與 FormData

進行行動網站的bug修改時,遇到其中一個需求是原本只使用 ajax 上傳string格式的input資料,但因為功能擴充除了原本的值要上傳外還需要上傳檔案類型的資料,大部分人都知道,使用 ajax 上傳圖片或檔案需要使用js的FormData物件,若是 ajax 傳遞的資料不包含檔案類型的則基本上都是使用一般的js物件傳遞即可。但其實很多人在遇到同時要傳遞一般input資料及檔案時就會猶豫要如何處理,或是直接將兩件事情分開來做,一是不知道後端如何處理,二是formdata傳送方法的前端return不像一般ajax可設定return物件要被解析的類型(例如text或json),導致有許多人會搞不懂其運作模式,但其實字串跟檔案是可以透過formdata一起傳送到後端處理的,為了讓大家使用上邏輯更為清晰所以撰寫此篇文章作為紀錄。

ajax 實例

先以傳送formdata的 ajax 當作例子講解
let data = new FormData();
先建立一個formdata物件

data.append(“value1”, $(‘#value1).val());
data.append(“value2”, $(‘#value2).val());
data.append(“value3”, $(‘#value3).val());
塞字串資料給formdata

data.append(“file”, $(‘#file’)[0].files[0]);
塞檔案資料給formdata

ajax 之範例圖
解釋一下contentTypeprocessData這兩個參數的用途,一般可能都是照著別人給的範例用沒有仔細去了解其用途,但其實在傳遞formdata的時候這兩個參數尤為重要。

contentType

contentType指定了要傳送的資料類型,它是一個字串值,通常設定為下列其中一種:

“application/x-www-form-urlencoded”:這是預設值,它會將傳送的資料編碼成URL格式,並以字串的形式傳送。這種資料類型通常用於傳送表單資料。
“multipart/form-data”:這種資料類型可以用來傳送二進位資料,例如圖片或檔案。這種資料類型通常用於檔案上傳等功能。
“application/json”:這種資料類型可以用來傳送JSON格式的資料,常用於RESTful API等場景。

如果填為false,則表示讓jQuery自行判斷類型。

processData

processData設定為false表示不對傳送的資料進行處理,直接傳送到伺服器端。如果設定為true,則會將傳送的資料進行處理,通常是將其轉換成URL格式的字串。通常在使用FormData傳送表單資料或傳送二進位資料時,將processData設為false,因為這些資料已經經過特殊處理,不需要再進行轉換。而在傳送JSON格式的資料時,則需要將processData設為false,否則會將JSON格式的字串轉換成URL格式,導致伺服器端無法正確解析。

在沒有特別設定的情況下(如上面這段範例ajax),返回值會是text型別,也就是單純的字串,需要使用JSON.parse函式將其轉換為json物件。

C# 後端接收實例

現在的controller都很聰明,會自動用formdata值的名稱對應傳入的參數名稱,基本上就是檔案用IFormFile接,其他用string接就不會出什麼問題。

ajax 之範例圖

結論

其實formdata的ajax型態應用比較廣,基本上其他寫法跟型別傳法的ajax也都可以用formdata的傳送模式去實作,所以其實這個方法記錄下來比較通用,甚至可以寫成自己習慣的格式讓自己在前後端串接上更節省時間,雖然現在在網路上下下關鍵字都可以獲得範例,寫法也百百種,但我覺得理解每一個常用的參數涵義及運作模式才會在出現少數bug時查明原因。

Comments

No comments yet. Why don’t you start the discussion?

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料