在 Struts2 專案中使用 jQuery AJAX 提交表單時,常遇到兩個經典問題:CKEditor 富文本內容為空,以及 Action 返回結果頁面無法跳轉。本文梳理根因並給出完整解決方案。
原因:CKEditor 實際將內容寫入隱藏的 <textarea>,但 $("#form").serialize() 或 FormData 只會讀取 <input>/<select> 等標準表單元素,不會自動同步 CKEditor 實例的最新內容到 textarea。
解決方案:提交前手動調用 CKEDITOR.instances[editorId].updateElement(),或直接讀取實例內容追加到請求數據。
// 方案 A:同步所有 CKEditor 實例
for (var instance in CKEDITOR.instances) {
CKEDITOR.instances[instance].updateElement();
}
var formData = $("#sendmail").serialize(); // 現在 textarea 已有最新值
// 方案 B:手動構建數據(適用於 $.ajax)
var content = CKEDITOR.instances.guide_content.getData();
var parm = $("#sendmail").serialize() + "&guide_content=" + encodeURIComponent(content);
原因:AJAX 請求屬於異步 HTTP 請求,瀏覽器不會自動處理 302 重定向或直接渲染返回的 HTML 頁面。Struts2 Action 返回 "sendMailSuccess" 對應的 JSP 只是作為 AJAX 響應文本返回給 success 回調的 data 參數。
解決方案:
window.location.href。<form id="sendmail" action="<%=basePath%>user/sendMail!sendEmail.action" method="post">
<textarea id="guide_content" name="guide_content" class="ckeditor"></textarea>
<input type="submit" value="發送" onclick="syncCKEditor()">
</form>
<script>
function syncCKEditor() {
for (var i in CKEDITOR.instances) {
CKEDITOR.instances[i].updateElement();
}
return true; // 繼續原生提交
}
</script>
後端 Action 保持不變:
public String sendEmail() {
MailBean mailBean = setMailBean();
// 直接從 request 獲取同步後的 textarea 值
String tContent = request.getParameter("guide_content");
mailBean.setContent(tContent);
// ... 發送郵件邏輯
return "sendMailSuccess"; // 對應 struts.xml 中的 result 頁面
}
{success: true, redirectUrl: "..."},前端 window.location.href = data.redirectUrl。掌握這兩點,即可徹底解決 Struts2 + AJAX + CKEditor 的提交與跳轉難題。