原文鏈接參見406 Not Acceptable, 工作中偶然碰到的問題,已解決。這是一篇很好的參考,遂翻譯在此。
406 Not Acceptable: 是什么及如何解決
January 25, 2018 Andrew Powell-Morse
406 Not Acceptable是一個HTTP響應狀態碼,指示服務器無法實現客戶端的一個 Accept-標頭的請求響應。這通常是用戶代理(即瀏覽器)指定一個可接受的字符集(通過Accept-Charset)、語言(通過Accept-Language)等應響應的結果,並且服務器無法提供此類響應。
與大多數 HTTP 響應代碼一樣 — 尤其是那些指示錯誤的響應代碼 — 406 Not Acceptable 錯誤代碼的原因可能難以跟蹤和修復。具有 50 多個狀態代碼的潛在池,這些代碼表示客戶端、Web 應用程序、Web 服務器以及通常有多個第三方 Web 服務之間的復雜關系,這導致了在最佳情況下,確定特定狀態代碼的原因可能是一項挑戰。
在本文中,我們將通過查看可能導致消息的原因,以及一些用於診斷和調試此錯誤在您自己的應用程序中出現的錯誤提示來更詳細地檢查 406 Not Acceptable的內容。我們甚至會檢查一些最流行的內容管理系統 (CMS),以發現可能導致您自己的網站意外生成 406 Not Acceptable 的潛在問題區域。讓我們鑽研一下吧!
服務端-還是客戶端?
4xx 類別中的所有 HTTP 響應狀態代碼都被視為客戶端錯誤響應。此類別與 5xx 分類錯誤(如我們幾個月前探索的 504 網關超時錯誤)形成鮮明對比,這些錯誤被視為服務器錯誤響應。也就是說,出現 4xx 錯誤並不一定意味着問題出在客戶端,這里的"客戶端"是指用於訪問應用程序的 Web 瀏覽器或設備。通常,如果您嘗試在您自己的應用程序中診斷問題,可以立即忽略大多數客戶端代碼和組件,如 HTML、級聯樣式表 (CSS)、客戶端 JavaScript 等等。這也不僅僅適用於網站。許多實現時髦用戶界面的智能手機應用程序實際上由后台的正常 Web 應用程序提供支持,而這些應用程序只是對用戶來說簡單地隱藏起來而已。
另一方面,服務器可能是 406 Not Acceptable 錯誤的根本原因。在某些情況下,服務器可能配置錯誤,並且不正確地處理了請求,這可能導致 406 代碼響應和其他有疑問的流量路由問題。我們將在下面探討其中一些場景(和潛在的解決方案),但請注意,即使 406 Not Acceptable 被視為客戶端錯誤響應,在這個場景下它本質上並不意味着我們可以排除客戶端或服務器作為此問題的罪魁禍首。在這些場景下,服務器仍然是生成 406 Not Acceptable 的網絡對象,並將其作為 HTTP 響應代碼返回給客戶端,但可能是客戶端以某種方式導致這個問題的。
從全面應用備份開始
和任何事情一樣,最好在開始的時候就安全地玩轉起來,而不是把事情搞砸,然后不久以后在路上后悔。因此,在嘗試對系統進行任何修復或更改之前,對你的應用程序、數據庫以及網站或應用程序的所有其他組件執行完整備份至關重要。更妙的是,如果你有能力,請創建應用程序的完整備份,並將這個備份存儲在非活動或公眾無法訪問的輔助暫存服務器上。這將為您提供一個干凈的測試場,用於測試解決問題的所有潛在修補程序,而不會威脅實時應用程序的安全性或神聖性。
診斷一個406 Not Acceptable 錯誤
如簡介中所述,406 Not Acceptable 表示用戶代理(在大多數情況下是 Web 瀏覽器)請求了有效的資源,但請求包含一個特殊的 Accept- 標頭,該標頭向服務器指示有效響應只能包含特定類型的信息。下面是此類場景的幾個栗子:
- 用戶代理可能本地化為服務器無法提供的特定區域設置或語言。例如,用戶代理可以使用 Accept-Language 請求標頭來指定有效的法語語言(Accept-Language:fr),但如果服務器無法使用法語提供響應,則 406 代碼可能是唯一正確的響應。
- 用戶代理可能請求服務器返回特定類型的內容。這些內容類型通常稱為 MIME 類型,用於定義如純文本(text/plain)、PNG 圖像(image/png)、mp4 視頻(video/mp4)等內容。因此,客戶端可以在請求中包含 Accept 標頭,並定義應由服務器提供的顯式 MIME 類型(例如,Accept:application/xml)。如果服務器無法響應請求的匹配內容類型,則可能需要 406 Not Acceptable 響應。
在 HTTP 請求中可以提供少量其他 Accept- 標頭,但絕大多數場景與上述類似:用戶代理需要顯式類型的響應,服務器要么提供響應,要么返回 406 代碼以指示它無法實現請求。
客戶端故障排除
既然 406 Not Acceptable 是客戶端錯誤響應代碼,因此最好首先排除可能導致此錯誤的任何潛在客戶端問題。下面是一些提示,用於在出現問題的瀏覽器或設備上嘗試下。
檢查請求的URL
406 Not Acceptable 的最常見原因是僅僅輸入了不正確的 URL。許多服務器都受到嚴密保護,因此不允許對客戶端/用戶代理不應訪問的資源發出意外請求。可能是請求的 URL 稍有錯誤,從而導致用戶代理請求特定類型的響應。例如,對 URI https://airbrake.io?json 的請求可能會向服務器指示需要 JSON 響應。由於 406 代碼不如 404 代碼常見,因此 406 的出現可能意味着請求的 URL 有效,但瀏覽器可能會誤解預期的請求類型。無論采用哪種方式,仔細檢查返回 406 Not Acceptable 錯誤的確切 URL以確保它是預期資源是一個好主意。
調試通用平台
如果你在得到 406 Not Acceptable 響應的服務器上運行常見軟件包,則可能需要首先查看這些平台的穩定性和功能。最常見的內容管理系統——如 WordPress、Joomla!和 Drupal——通常都是經過精心測試的,但一旦您開始對基礎擴展或 PHP 代碼(這個語言幾乎用在所有現代內容管理系統)進行了修改,將很容易導致不可預見的問題,進而導致 406 Not Acceptable 錯誤。
下面有幾個提示,旨在幫助您解決這些流行的軟件平台故障。
回滾最近升級
如果您最近剛好在 406 Not Acceptable 錯誤出現之前更新了內容管理系統本身,您可能需要考慮回滾到在工作正常時安裝的早期版本。同樣,您最近升級的任何擴展或模塊也可能導致服務器端問題,因此還原到這些擴展或模塊的早期版本也可能有所幫助。要獲得此任務的幫助,只需使用搜索"降級 [平台名稱]"然后跟進即可。然鵝,在某些情況下,某些 CMSs 並不真正提供版本降級功能,這表明他們認為基本應用程序以及發布的每個新版本都極其穩定且無錯誤。對於較流行的平台,典型情況就是如此,所以如果您找不到將平台還原到舊版本的簡單方法,請不要害怕。
卸載新擴展、模塊或插件
根據您的應用程序使用的特定內容管理系統,這些組件的確切名稱將有所不同,但它們在每個系統中都具有相同的用途:改進平台的功能和特性,使其超出其通常的預期。但請注意:這些擴展或多或少可以完全控制系統,並幾乎可以進行任何更改,無論是對 PHP 代碼、HTML、CSS、JavaScript 還是數據庫。因此,卸載最近可能添加的任何新擴展可能是明智的。再說一次,通過搜索這些擴展的名稱以獲取這個進程的官方文檔和協助。
檢查意外的數據庫更改
值得注意的是,即使您通過 CMS 儀表板卸載了擴展,也不保證該擴展所做的更改已完全還原。對於許多 WordPress 擴展來說尤其如此,這些擴展在應用程序中提供全權委托,包括數據庫的完全訪問權限。除非擴展作者在代碼中顯式編碼此類內容,否則在某些場景下,擴展可能會修改不"屬於"擴展本身,而是由其他擴展(甚至基本 CMS 本身)創建和管理的數據庫記錄。在這些情況下,擴展可能不知道如何還原對數據庫記錄的更改,因此在卸載期間將忽略此類內容。診斷此類問題可能比較棘手,但我本人多次遇到此類情況,因此,假設您有理由相信擴展可能是 406 Not Acceptable 的罪魁禍首,因此,您的最佳操作方案是打開數據庫,手動查看可能由擴展修改的表和記錄。
最重要的是,不要害怕搜索你的問題。嘗試搜索與您的問題相關的特定術語,例如應用程序的 CMS 名稱隨同 406 Not Acceptable。你很有可能會找到經歷過同樣問題的人。
服務器端的故障排除
如果您未運行 CMS 應用程序——或者即使您運行了 CMS 應用程序,但您確信 406 Not Acceptable 與該應用程序無關——下面是一些其他提示,可幫助您解決在服務器端可能導致的此類問題。
確認您的服務器配置
您的應用程序可能在使用兩個最流行的 Web 服務器軟件之一 Apache 或 nginx 的服務器上運行。在發布時,這兩個網絡服務器軟件占了世界上所有網絡服務器軟件的 84%!因此,您可以采取的第一步,以確定是什么可能導致這些 406 Not Acceptable 響應代碼是檢查您的 Web 服務器軟件的配置文件是否無意的重定向或請求處理指令。
要確定您的應用程序正在使用哪個Web 服務器,您需要查找一個密鑰文件。如果您的 Web 服務器是 Apache,則在網站文件系統的根目錄中查找 .htaccess 文件。例如,如果您的應用程序位於共享主機上,則可能具有與托管帳戶關聯的用戶名。在這種情況下,應用程序根目錄通常位於 /home/
如果找到 .htaccess 文件,然后在文本編輯器中打開該文件,並查找使用 RewriteXXX 指令的行,這些指令是 Apache 中mod_rewrite模塊的一部分。但是,涵蓋這些規則如何工作完全超出了本文的范圍,但基本概念是,RewriteCond 指令定義了一個基於文本的模式,該模式將與輸入的 URL 匹配。如果站點的訪問者請求了匹配的 URL,則遵循一個或多個 RewriteCond 指令的 RewriteRule 指令用於執行請求到相應 URL 的實際重定向。
例如,下面是一個簡單的RewriteRule,它匹配所有傳入中不包含Accept:application/json 標頭的請求到https://airbrake.io/users/json。結果是重定向和 406 Not Acceptable 的響應錯誤代碼:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/users/json/?.*$
RewriteCond %{HTTP_ACCEPT} !application/json
RewriteRule ^(.*)$ http://airbrake.io/users/json$1 [R=406,L]
請注意RewriteRule末尾的 R=406 標志,該標志明確聲明響應代碼應為 406,向用戶代理指示資源存在,但無法實現顯式 Accept- 標頭。因此,如果您在 .htaccess 文件中發現任何看似非我同類的奇怪的 RewriteCond 或 RewriteRule 指令,請嘗試暫時注釋掉它們(使用 # 字符前綴),然后重新啟動 Web 服務器以查看這是否解決了問題。
另一方面,如果您的服務器在 nginx 上運行,則需要查找完全不同的配置文件。默認情況下,此文件名為 nginx.conf,位於幾個通用目錄之一:/usr/local/nginx/conf、/etc/nginx 或 /usr/local/etc/nginx。找到以后,在文本編輯器中打開 nginx.conf 並查找使用 406 響應代碼標志的指令。例如,下面是一個簡單的塊指令(即一組命名的指令),該指令為airbrake.io配置虛擬服務器,並確保與上述類似,對不包括Accept:application/json 請求標頭至 https://airbrake.io/users/json 的請求將會失敗,並且返回 406 響應代碼:
server {
listen 80;
listen 443 ssl;
server_name airbrake.io;
location /users/json
{
if ($http_accept != application/json)
{
return 406 https://airbrake.io/users/json$request_uri;
}
}
}
請查看 nginx.conf 文件,了解包含 406 標志的任何異常指令或行。在重新啟動服務器之前注釋掉任何異常,以查看問題是否得到解決。
每種不同類型的 Web 服務器的配置選項可能巨大差異,因此,我們將僅列出一些流行的項目,以便為您提供一些資源,具體取決於您的應用程序在哪種類型的服務器上運行:
- Apache
- Nginx
- IIS
- Node.js
- Apache Tomcat
查看日志
幾乎每個 Web 應用程序都會保留某種形式的服務器端日志。應用程序日志通常是應用程序所執行操作的歷史記錄,例如請求了哪些頁面、它連接到哪些服務器、它提供的哪些數據庫結果,等等。服務器日志與運行應用程序的實際硬件相關,並且通常會提供有關所有已連接服務的運行狀況和狀態的詳細信息,甚至僅提供服務器本身的詳細信息。如果您使用的是 CMS,搜索"日志 平台名稱";如果您正在運行自定義應用程序,則使用"日志 編程語言"和"日志 操作系統"來進行搜索,以獲取有關查找出現問題相關日志的詳細信息。
調試應用程序代碼或腳本
如果所有其他操作都失敗,可能是應用程序中某些自定義代碼中的問題導致了該問題。嘗試通過手動調試應用程序以及分析應用程序和服務器日志來診斷問題可能來自何處。理想情況下,將整個應用程序的副本復制到本地開發計算機,並執行分步調試過程,這將允許您重新創建發生 406 Not Acceptable 的確切場景,並在錯誤發生時查看應用程序代碼。
無論原因是什么——即使您這次設法修復了它——在您自己的應用程序中出現類似 406 Not Acceptable 的問題,他們發生的時刻都是您可能想要實現錯誤管理工具的良好指示,它將幫助您自動檢測錯誤並會提醒你。Airbrake 的錯誤監控軟件可為您的所有開發項目提供實時錯誤監控和自動異常報告。Airbrake 最先進的 Web 儀表板可確保您收到有關應用程序運行狀況和錯誤率的全天候狀態更新。無論您從事什么工作,Airbrake 都可以輕松與所有最流行的語言和框架集成。此外,Airbrake 還可以輕松自定義異常參數,同時讓您完全控制活動錯誤濾清系統,因此您只收集最重要的錯誤。
現在就來看看 Airbrake 的錯誤監控軟件吧,親自了解為什么這么多世界上最好的工程團隊使用 Airbrake 來徹底改變其異常處理實踐!