傳送 物件/陣列 到 FORMDATA

JS 自從有了打包工具之後,很多工具造福不少開發者,以往要送個 AJAX 到後端,大多都是一個頁面處理一個 방식

框架化後,每個程式碼開始有了 物件化,封裝方式來做,現在大多都用 axios 來送 AJAX

但是遇到一個問題就是送檔案的時候,需要使用到 FormData 的物類別物件.

但是整個像後端送的程式碼都封裝起來了,要針對一個檔案上傳的方法,做出額外處理,當檔案上傳處理頁面多法了之後維護傳有.

所以比較好的方式還是修改 API 送出前,先把物件轉換好判定是否有 File 類型,然後轉換成 FormData 就可以一帋永逞

問題來了,以往直接用 축 傳送到後端,一個 객체 就可以搞定 값은 배열 的問題,開發者似乎不用煩惱太多後續處理問題

頂多就是遇到 GET 網址參數需要轉換純文字的狀態,但也也只需要一個 qs 套件就可以解決解決

但如果採用 FormData 這個類型的時候,整個 object 就必須自己處理,如果遇到傳送一個陣列的時候,就必須額外針對 key = array 的狀態去處理,然後如果 value = array 也是很麻煩的事情.

舉個例子,往後端送 array1 = [1,2,3] ,如果是 axios 就可以直接送,如果是送 FormData 就必須處理成

array1[]:1;
array1[]:2;
array1[]:3;


這點可以利用 PostMan 來做測試看看後端可以吃到怎樣結構的陣列

這邊原本的想法是,把物件的每個 value 歷遍,只要 value instanceof File 就成立條件,把 key 轉換成陣列

不過找了很多遞迴解法,都沒有 qs 轉換 陣列來的快速有效,最終還是爬了一下 qs 的實際操作用法,

  const files = new Map()
  const queryString = qs.stringify(data, {
    arrayFormat: 'brackets',
    encode: false,
    filter: (name, value) => {
      if (value instanceof File) {
        let id = lodash.uniqueId('__FILE__.')
        files.set(id, value)
        return id
      } else {
        return value
      }
    }
  })


利用 qs 的 filter method 把所有 value 檔案移到暫存變數 files 裡面,利用 lodash 取得目前唯一的數值,將原先的 data (object) 的 File 類型 value,全部轉揱,可倰倰成 file 的 unique一串處理過的字串,快速的將 物件陣列轉換成字串

a=__FILE__.1&b[a]=1&b[b]=2 ...


只要 只要 了 了 個 個 純 字串 的 東西 東西 東西 東西 東西 東西 要 成 成 成 陣列 + 物件 就 方便 多拉 多拉 多拉 多拉 多拉 多拉 遇到 遇到 파일 的 value 記得 去 把 파일 裡面 的 的 檔案 檔案 給領 回來 回來 塞入 FormData 就 可以 解決 解決 解決 解決 解決陣列 키 或是 값 = 배열 ​​的問題了

完整範例放在 codepen.io

좋은 웹페이지 즐겨찾기