首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

複製貼上釀成的慘劇:Spring 文件下載誤用 HttpStatus.CREATED (201) 導致 IE 失敗

     編輯:Java 綜合教學

一個 HTTP 狀態碼錯誤引發的跨瀏覽器兼容性血案

網上流傳的 Spring 文件下載「最佳實踐」代碼中,返回狀態碼使用 HttpStatus.CREATED (201)。這在 Chrome/Firefox 表現正常,但在 IE 下導致下載失敗或彈出異常提示。本文還原排查過程,正本清源 HTTP 語義,給出正確寫法。

問題代碼(廣泛流傳的錯誤示範)

@RequestMapping("download")
public ResponseEntity<byte[]> download() throws IOException {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    headers.setContentDispositionFormData("attachment", "xxx.txt");
    // 錯誤:使用 201 Created
    return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(getDictionaryFile()), headers, HttpStatus.CREATED);
}

現象與誤區

  • Chrome/Firefox:正常下載,無任何報錯 → 產生「代碼無誤」錯覺。
  • IE:下載失敗、或彈出「無法下載」提示、或返回空白頁。
  • 排查方向偏差:一度懷疑 MediaType、Header 寫法、文件流讀取等,嘗試多種組合無效。

根因:HTTP 201 語義與 IE 的嚴格執行

HttpStatus.CREATED (201) 含義:請求已成功,服務器創建了新資源,且響應頭 Location 應包含新資源的 URI。

文件下載場景:服務器只是讀取現有文件返回,並未創建新資源,也無 Location 頭。IE 依據 RFC 2616 嚴格校驗:收到 201 卻無 Location,判定為協議違背,拒絕處理響應體。Chrome/Firefox 容錯較寬鬆,直接忽略狀態碼處理流。

正確寫法:使用 200 OK

@RequestMapping("download")
public ResponseEntity<byte[]> download() throws IOException {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    headers.setContentDispositionFormData("attachment", "xxx.txt");
    // 正確:200 OK 表示成功返回資源內容
    return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(getDictionaryFile()), headers, HttpStatus.OK);
}

擴展:常見下載響應狀態碼選擇表

場景狀態碼說明
正常文件下載200 OK成功返回資源內容
斷點續傳/範圍請求206 Partial Content配合 Range 請求頭
文件不存在404 Not Found資源不存在
無權限403 Forbidden認證/授權失敗

教訓總結

  1. 拒絕盲目複製:網上代碼未必經過多瀏覽器驗證,必須理解每行語義。
  2. HTTP 語義是基石:狀態碼不是裝飾,代表服務器與客戶端的契約。
  3. 兼容性測試不可少:至少覆蓋 IE/Edge、Chrome、Firefox、Safari 主流內核。
  4. 查閱權威文檔:RFC 7231 / MDN HTTP Status Codes 是最終裁判。

將 HttpStatus.CREATED 改為 HttpStatus.OK,問題瞬間解決。這一行代碼的修改,背後是對 HTTP 協議語義的敬畏。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved