DEV Community

Mesak
Mesak

Posted on • Edited on • Originally published at mesak.tw

傳送 物件/陣列 到 FORMDATA

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

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

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

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

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

問題來了,以往直接用 axios 傳送到後端,一個 object 就可以搞定 value is array 的問題,開發者似乎不用煩惱太多後續處理問題

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

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

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

array1[]:1;
array1[]:2;
array1[]:3;
Enter fullscreen mode Exit fullscreen mode

這點可以利用 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
      }
    }
  })
Enter fullscreen mode Exit fullscreen mode

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

a=__FILE__.1&b[a]=1&b[b]=2 ...
Enter fullscreen mode Exit fullscreen mode

只要有了這個純字串的東西,要拆解成陣列 + 物件就方便多拉,拆完之後遇到 FILE 的 value 記得去把 files 裡面的檔案給領回來,這樣塞入 FormData 就可以解決陣列 key 或是 value = array 的問題了

完整範例放在 codepen.io

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay