2020/01/17

form + API 的兩種方式比較

一個 form post 也可以繞個一大圈


網頁傳統 form 要傳遞參數值時,會使用 action,寫法大致如下:

  <form action="http://localhost:8080/login" method="post">
    <h1>Form Action Test</h1>
    <input type="text" name="email" value="Eden" />
    <input type="password" name="password" value="L@veEden" />
    <input type="submit" value="Submit">
  </form>

可以看到 submit 時,Request 的 Content-Type 屬性是很標準的 application/x-www-form-urlencoded。



這個方式很標準,絕大部份的 Web Server 都可以接受,當然也包含了 Delphi Web Server。

時代在進步,JavaScript 標準都來到 2020,所以當然要試一下新的操作方法。

JavaScript 裡有 FormData 類別,可以建構 form 物件,寫法如下:

  <form id="login-form" onsubmit="handleSubmit(event)">
    <input type="text" name="email" value="Eden" />
    <input type="password" name="password" value="L@veEden" />
    <input type="submit" value="Submit">
  </form>
  
  <script>
  function handleSubmit(event) {
    event.preventDefault()
    let formData = new FormData(document.getElementById('login-form'))

    fetch("http://localhost:8080/login", {
      method: "POST",
      body: formData
    })
  }
  </script>

實際 submit 時 Request 的 Content-Type 屬性是 multipart/form-data,如下圖所示:




multipart/form-data 相對於 application/x-www-form-urlencoded 比較少見,故某些 Web Server 預設是不會處理 multipart/form-data 的格式內容。

既然後端需要做調整,如果前端事先做好,那後端不就更省事?

前端調整

仿照傳統規則

前端仿照傳統的作法實作,程式碼如下:

  <form id="login-form" onsubmit="handleSubmit(event)">
    <input type="text" name="email" value="Eden" />
    <input type="password" name="password" value="L@veEden" />
    <input type="submit" value="Submit">
  </form>
  
  <script>
  function handleSubmit(event) {
    event.preventDefault()
    let formElement = document.getElementById("login-form")
    let formData = ""
    formData = "email=" + formElement[0].value
    formData = formData + "&password=" + formElement[1].value
    fetch("http://localhost:8080/login", {
      method: "POST",
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      body: formData
    })
  }
  </script>

執行結果


修改後就能讓 Web Server 順利解析參數。

使用 URLSearchParams

URLSearchParams 是個處理各種URL查詢參數轉換的類別,在這個例子只需要將 FormData 再丟入 URLSearchParams 處理過,即能得到 application/x-www-form-urlencoded 所需的查詢參數,程式如下所示:

<html>
<head></head>
<body>
  <form id="login-form" onsubmit="handleSubmit(event)">
    <input type="text" name="email" value="Eden" />
    <input type="password" name="password" value="L@veEden" />
    <input type="submit" value="Submit">
  </form>
  
  <script>
  function handleSubmit(event) {
    event.preventDefault()
    let formData = new FormData(document.getElementById('login-form'))
    var searchParams = new URLSearchParams(formData);
    fetch("http://localhost:8080/login", {
      method: "POST",
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      body: searchParams
    })
  }
  </script>
</body>
</html>

執行結果


一樣修改後就能讓 Web Server 順利解析參數。


總結

新方法但沿用舊觀念,在某些前端框架看不到的細節還是要拆成香草JS小部件來多做嘗試才行。

前端修改下我會偏好使用 URLSearchParams,在開發上比較省力,程式也比較好懂。

以上提供各位參考。謝謝大家收看!


See also


沒有留言:

張貼留言