$.ajax 請求 Servletout.print 輸出 JSON 字串success 回調不執行,進入 error 回調eval 解析也失敗jQuery 1.4+ 版本嚴格要求 dataType: "json" 時,回應必須是標準 JSON 格式,否則不觸發 success 回調。
// 錯誤 1: 單引號而非雙引號
out.print("[{'Cno':'C001','Cth1':'Chapter1'}]");
// 錯誤 2: 尾隨逗號
out.print("[{\"Cno\":\"C001\",\"Cth1\":\"Chapter1\",}]");
// 錯誤 3: 非陣列非物件
out.print("{\"Cno\":\"C001\",\"Cth1\":\"Chapter1\"}"); // 但前端當陣列處理
// 正確:雙引號、無尾隨逗號、正確結構
out.print("[{\"Cno\":\"C001\",\"Cth1\":\"Chapter1\"}]");
// 或使用 JSON 庫生成 (推薦)
$.ajax({
type: "POST",
url: "ShowDetail",
data: { Cno: Cno }, // 使用 data 物件,避免手動拼接 URL
dataType: "json", // 關鍵:告訴 jQuery 期望標準 JSON
success: function(data) {
// data 已自動解析為 JS 物件/陣列
if (data && data.length > 0) {
console.log("第一筆 Cth1:", data[0].Cth1);
// 處理資料...
}
},
error: function(xhr, status, error) {
console.error("AJAX 請求失敗:", status, error);
console.error("回應內容:", xhr.responseText);
}
});
@WebServlet("/ShowDetail")
public class ShowDetailServlet extends HttpServlet {
private ObjectMapper mapper = new ObjectMapper(); // Jackson
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String cno = req.getParameter("Cno");
// 模擬資料查詢
CourseDetail cd = courseService.findByCno(cno);
// 設定回應標頭 (關鍵!)
resp.setContentType("application/json;charset=UTF-8");
resp.setCharacterEncoding("UTF-8");
// 使用 JSON 庫序列化 (避免手動拼接錯誤)
String json = mapper.writeValueAsString(cd);
resp.getWriter().write(json);
}
}
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
| 坑點 | 現象 | 解決 |
|---|---|---|
| Content-Type 錯誤 | 瀏覽器不識別為 JSON | resp.setContentType("application/json;charset=UTF-8") |
| 手動拼接 JSON | 易出現語法錯誤 (引號、逗號、轉義) | 使用 Jackson/Gson/JSON-B 序列化 |
| 回應非標準 JSON | success 不執行 | 確保輸出符合 RFC 8259 標準 |
| 前端當物件當陣列 | data.Cth1 undefined | 檢查結構:data[0].Cth1 (陣列) vs data.Cth1 (物件) |
| 中文亂碼 | 回應中文顯示亂碼 | 設定 charset=UTF-8,確保編譯編碼一致 |
| 同步請求阻塞 UI | 頁面卡死 | 移除 async: false (已棄用),使用 Promise/async-await |
// 定義統一回應類
public class ApiResponse<T> {
private int code; // 200 成功,其他失敗
private String message;
private T data;
// getter/setter...
}
// Servlet 中使用
ApiResponse<CourseDetail> response = new ApiResponse<>();
response.setCode(200);
response.setData(cd);
resp.getWriter().write(mapper.writeValueAsString(response));
// 前端處理
success: function(res) {
if (res.code === 200) {
console.log(res.data.Cth1);
} else {
alert("錯誤: " + res.message);
}
}
error 回調中印出 xhr.responseTextAJAX 請求 Servlet 返回 JSON 的核心原則:後端使用成熟 JSON 庫序列化 + 設定正確 Content-Type,前端信任 jQuery 自動解析。拒絕手動拼接 JSON 字串,這是 90% 問題的根源。