使用 Accept 判斷請求格式:如何實現靈活的錯誤處理?

更新日期: 2025 年 1 月 1 日

本文為 Django + Vue 前後端分離解析,第 12 篇

  1. 前後端分離的 404 錯誤處理:步驟指南
  2. 正常網頁與 API 接口:新手指南
  3. GraphQL 與 REST:理解新時代的 API 設計
  4. 為什麼自定義 404 頁面需要同時支持 API 和 HTML:新手指南
  5. 前後端分離中的路由與錯誤處理:新手指南
  6. 設計後端 API 的 404 錯誤處理:新手指南
  7. 前端與後端的 HTTP 請求與響應協議
  8. Django 中自定義 404 專案架構的最佳實踐
  9. 深入理解 Django 中的自定義 404 views 函數處理解析
  10. Django 的 handler404:自定義 404 錯誤頁面的核心
  11. Django 的 render 函數與 status 參數:為什麼重要?
  12. 使用 Accept 判斷請求格式:如何實現靈活的錯誤處理? 👈 所在位置
  13. 使用 Esbuild 搭建 Vue 開發環境的指南
  14. 新手入門:TailwindCSS 與 DaisyUI 的整合指南
  15. Django 靜態文件管理:static 與 staticfiles 完整指南
  16. 使用 WhiteNoise 簡化 Django 靜態文件管理:新手入門指南
  17. Vue 與 Django 整合:從編輯到部署的完整指南
  18. Django 與 Vue 的專案目錄與設計流程指南
  19. Django + Vue 前後端分離架構:後端路由渲染解析
  20. Vue 3 應用的主入口詳解:如何初始化應用
  21. 探索 Vue 應用的根組件:App.vue 的角色與設計
  22. Vue.js 單頁應用(SPA)邏輯與運作流程詳解
  23. 新手指南:使用 Axios 實現高效的 HTTP 請求
  24. 在 Vue 中處理 404 錯誤組件(component)設計:新手指南
  25. Vue Router 新手指南:設置 404 錯誤頁面

處理 404 錯誤時,我們通常需要根據請求來源返回不同的內容:

  • 對於 API 請求:返回 JSON 格式的結構化錯誤信息。
  • 對於瀏覽器請求:返回一個友好的 HTML 錯誤頁面。

本文將帶你了解如何基於 Accept 標頭的值來設計這樣的邏輯,以及如何測試它的正確性。


HTTP 請求頭與 Accept 的作用

Accept 是什麼?

Accept 是 HTTP 請求頭中的一個字段,用於告訴伺服器客戶端希望接收到的內容格式。

例如:

  • Accept: application/json 表示希望獲取 JSON 格式的響應。
  • Accept: text/html 表示希望獲取 HTML 格式的響應。

伺服器根據 Accept 的值決定返回什麼樣的內容,從而實現對不同請求類型的兼容。

瀏覽器的默認行為

當用戶直接在瀏覽器中訪問 URL 時,瀏覽器會自動在請求頭中加入一個 Accept 值,類似以下內容:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  • 首選項是 text/html:瀏覽器希望接收到 HTML 格式的內容。
  • application/json 不會包含在內:因為 JSON 格式通常用於 API,而不是用戶瀏覽的普通頁面。

API 請求的行為

當前端代碼(例如 fetchaxios)發送 API 請求時,通常會指定 Accept 值為 application/json,要求伺服器返回 JSON 格式的數據。

例如:

fetch('/404', {
    method: 'GET',
    headers: {
        'Accept': 'application/json'
    }
}).then(response => response.json())
  .then(data => console.log(data));

這樣,伺服器就可以檢測到 Accept 值,並根據需求返回適合的格式。


基於 Accept 的錯誤處理邏輯

以下是設計邏輯和代碼示例,用於根據請求的 Accept 值返回不同的內容。

設計邏輯

  1. 檢測 Accept
    從請求頭中提取 Accept,判斷是否包含 application/json
  2. 返回格式選擇
    • 如果是 API 請求,返回 JSON 格式的錯誤信息。
    • 如果是瀏覽器請求,返回 HTML 錯誤頁面。

代碼實現

以下是自定義 404 錯誤處理函數的代碼:

from django.http import JsonResponse
from django.shortcuts import render

def custom_404_view(request, exception):
    if "application/json" in request.headers.get("Accept", ""):
        return JsonResponse({
            "error": "Page not found",
            "status_code": 404,
            "detail": "The requested URL was not found on this server."
        }, status=404)
    else:
        return render(request, "404.html", status=404)

代碼解析

  1. 檢查 Accept
    • 使用 request.headers.get("Accept", "") 提取 Accept 值。如果不存在,返回空字符串,避免出錯。
    • 檢查 Accept 是否包含 application/json,判斷這是否是一個 API 請求。
if "application/json" in request.headers.get("Accept", ""):
  1. 返回 JSON 格式
    • 使用 JsonResponse 返回結構化的 JSON 數據,包含錯誤信息和狀態碼。
return JsonResponse({
    "error": "Page not found",
    "status_code": 404,
    "detail": "The requested URL was not found on this server."
}, status=404)
  1. 返回 HTML 格式return render(request, "404.html", status=404)
    • 使用 render 渲染一個 HTML 模板作為錯誤頁面,並設置狀態碼為 404。

如何測試此邏輯?

測試瀏覽器請求

  • 在瀏覽器中訪問一個不存在的路徑,例如:http://127.0.0.1:8000/404
  • 預期結果:後端返回一個友好的 HTML 錯誤頁面。

測試 API 請求

使用工具(如 Postman 或 cURL)模擬 API 請求:

Postman 測試

  1. 打開 Postman,發送 GET 請求到一個不存在的路徑,例如:http://127.0.0.1:8000/api/nonexistent
  2. 在 Headers 中設置: Accept: application/json
  3. 預期結果:返回 JSON 格式的錯誤信息,類似:
{
    "error": "Page not found",
    "status_code": 404,
    "detail": "The requested URL was not found on this server."
}

cURL 測試

在終端中使用以下命令發送請求:

curl -H "Accept: application/json" http://127.0.0.1:8000/404
  • 預期結果:返回 JSON 格式的錯誤信息。

如果沒有特別設置 Accept

當客戶端未明確設置 Accept,後端會根據瀏覽器的默認值處理。

  • 通常返回 HTML 格式的頁面(因為 text/html 是瀏覽器的首選)。

總結

  1. Accept 是關鍵字段:它讓伺服器知道客戶端希望接收到什麼格式的內容。
  2. 靈活設計錯誤處理:根據 Accept 值判斷,返回 JSON 或 HTML,滿足 API 請求和瀏覽器請求的不同需求。
  3. 測試覆蓋:確保在不同請求場景下(API 和瀏覽器)響應格式正確。

通過這種方法,你的 Django 應用可以實現更加靈活和高效的錯誤處理,為前後端分離和普通用戶提供良好的體驗!

Similar Posts