使用Fetch API實現異步表單提交與按鈕狀態控制

使用Fetch API實現異步表單提交與按鈕狀態控制

本文旨在解決JavaScript啟用按鈕在傳統php表單提交后失效的問題。當表單通過同步方式提交時,頁面會完全重載,導致dom狀態重置,從而使JavaScript動態修改的按鈕狀態恢復到初始值。解決方案是利用Fetch API進行異步表單提交,避免頁面刷新,從而有效保留按鈕的啟用狀態,同時提升用戶體驗并實現更靈活的交互邏輯。

問題背景:同步表單提交與DOM狀態重置

在web開發中,我們常會遇到這樣的場景:一個表單包含多個按鈕,其中某個按鈕(例如“下載”按鈕)需要依賴于前一個操作(例如“提交”按鈕點擊并完成數據處理)才能啟用。通常,我們會使用javascript來動態啟用或禁用html元素

考慮以下經典示例:

<input id="saveForm" class="button_text" type="submit" name="submit" value="Submit" onclick="enableButton2()"/> <input id="saveFile" class="button_text" type="submit" name="download" value="Download" disabled/>  <script>     function enableButton2() {         document.getElementById("saveFile").disabled = false;     } </script>

這段代碼的意圖是,當用戶點擊“Submit”按鈕時,enableButton2()函數會被調用,從而啟用“Download”按鈕。然而,如果“Submit”按鈕的type屬性是submit,它會觸發一個傳統的表單提交行為。這個行為會導致整個頁面重新加載(即所謂的“硬刷新”)。頁面重載后,瀏覽器會重新解析html并構建DOM,此時saveFile按鈕會回到其初始的disabled狀態,使得JavaScript所做的更改失效。

這是因為傳統的表單提交是一個同步過程,它會將瀏覽器導航到新的URL(通常是表單的action屬性指定的URL),或者重新加載當前頁面。頁面一旦重新加載,所有客戶端的JavaScript狀態和DOM修改都會丟失。

解決方案:使用Fetch API進行異步表單提交

為了解決頁面重載導致狀態丟失的問題,我們需要避免傳統的同步表單提交。最佳實踐是使用JavaScript的異步通信技術,例如Fetch API,將表單數據發送到服務器,而無需刷新整個頁面。

Fetch API提供了一種現代、靈活的方式來發起網絡請求。通過Fetch API,我們可以在后臺向服務器發送數據,并在收到響應后,僅更新頁面中需要改變的部分,從而保持其他元素的現有狀態。

核心思路

  1. 修改觸發按鈕類型: 將作為觸發器的按鈕(例如“Submit”按鈕)的type從submit改為button,以防止其默認的表單提交行為。
  2. 使用FormData收集數據: 在JavaScript中,使用FormData對象來輕松收集表單中的所有數據。
  3. 使用Fetch API發送請求: 構建一個fetch請求,指定http方法(通常是POST)和請求體(FormData對象)。
  4. 處理服務器響應: 在fetch的then方法中處理服務器的響應。根據響應結果,決定是否啟用第二個按鈕。
  5. 錯誤處理: 捕獲網絡錯誤或服務器返回的非預期響應。

代碼實現

首先,修改HTML結構,將第一個按鈕的type改為button,并確保表單有一個id以便JavaScript獲取:

<form action="#" id="myForm">   <input id="saveForm" class="button_text" name="submit" type="button" value="Submit" onclick="submitFormAndEnableButton()" />   <input id="saveFile" class="button_text" type="submit" name="download" value="Download" disabled /> </form>

接下來,實現submitFormAndEnableButton() JavaScript函數,使用Fetch API發送數據:

<script>     function submitFormAndEnableButton() {         // 獲取表單元素         var formElement = document.getElementById('myForm');         // 使用FormData對象收集表單數據         var formData = new FormData(formElement);          // 使用Fetch API發送POST請求         fetch("your_php_script.php", { // 將 "your_php_script.php" 替換為實際處理表單的PHP文件路徑             method: "POST", // 指定請求方法為POST             body: formData  // 將FormData作為請求體發送         })         .then(function(response) {             // 檢查HTTP響應狀態碼是否在200-299之間(表示成功)             if (response.ok) {                 // 表單成功提交到服務器,可以在這里處理服務器返回的數據                 // 例如,如果php腳本返回json,可以使用 response.json()                 // response.text() 獲取純文本                 console.log("表單提交成功!");                 // 成功后啟用第二個按鈕                 document.getElementById('saveFile').disabled = false;                 // 可以在這里添加更多成功后的UI更新邏輯             } else {                 // HTTP狀態碼表示請求未成功(例如404, 500等)                 console.Error('網絡響應錯誤,狀態碼: ' + response.status);                 // 可以在這里處理失敗情況,例如顯示錯誤信息             }         })         .catch(function(error) {             // 捕獲網絡請求過程中發生的錯誤(例如斷網,URL錯誤等)             console.error('Fetch請求失敗:', error.message);             // 可以在這里處理網絡錯誤,例如提示用戶檢查網絡連接         });     } </script>

后端PHP腳本注意事項

服務器端的PHP腳本(your_php_script.php)應該處理接收到的數據,并返回一個HTTP狀態碼,通常是200 OK表示成功。PHP腳本不應執行頁面重定向或輸出完整的HTML頁面,而是應該輸出一個簡單的狀態(如JSON對象,或純文本的“success”/“error”)。

例如,一個簡單的PHP處理腳本可能如下:

<?php // your_php_script.php  if ($_SERVER["REQUEST_METHOD"] == "POST") {     // 假設你有一些數據要處理     $submit_value = $_POST['submit'] ?? '';     // ... 處理其他表單數據 ...      // 模擬一些處理時間     sleep(1);       // 根據處理結果返回響應     if (/* 數據處理成功 */ true) {         http_response_code(200); // 設置HTTP狀態碼為200 OK         echo json_encode(["status" => "success", "message" => "數據已成功保存"]);     } else {         http_response_code(500); // 設置HTTP狀態碼為500 Internal Server Error         echo json_encode(["status" => "error", "message" => "數據保存失敗"]);     } } else {     http_response_code(405); // Method Not Allowed     echo json_encode(["status" => "error", "message" => "只允許POST請求"]); } ?>

總結

通過將傳統的同步表單提交替換為Fetch API實現的異步提交,我們成功避免了頁面重載,從而解決了JavaScript動態修改的DOM狀態(如按鈕的disabled屬性)在PHP處理后被重置的問題。這種方法不僅保持了前端狀態的持久性,還提供了更流暢的用戶體驗,因為用戶無需等待整個頁面刷新。此外,Fetch API的promise鏈式調用使得異步請求的成功和失敗處理更加清晰和現代化,是構建響應式Web應用的重要工具

? 版權聲明
THE END
喜歡就支持一下吧
點贊14 分享