事情是,Nginx完全按照你的要求去做。你可以通過調用curl -v http://localhost
(或者你使用的任何主機名)來驗證。結果將看起來有點像這樣:
* Rebuilt URL to: http://localhost/
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET/HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost
> Accept: */*
>
< HTTP/1.1 409 Conflict
* Server nginx/1.4.6 (Ubuntu) is not blacklisted
< Server: nginx/1.4.6 (Ubuntu)
< Date: Fri, 08 May 2015 19:43:12 GMT
< Content-Type: application/octet-stream
< Content-Length: 6
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
foobar
正如你所看到的,Nginx的同時返回409和foobar
,您訂購。
因此,這裏真正的問題是,爲什麼你的瀏覽器中顯示了相當格式化的錯誤頁面時,有返回代碼後沒有自定義文本,灰色「無法訪問」之一,當這樣的文本存在。
答案是:因爲Content-Type
頭的值。
的HTTP,一些響應代碼應該或必須附帶響應主體標準狀態。爲了符合標準,Nginx會這樣做:只要您返回一個沒有所需內容的特殊響應代碼,Web服務器就會將其自己的hardcoded HTML響應發送給客戶端。而這個迴應的一部分是標題Content-Type: text/html
。這就是爲什麼你看到那個漂亮的白色錯誤頁面,當你做return 409
沒有文本部分 - 因爲這個頭文件你的瀏覽器知道返回的數據是HTML並且它將它呈現爲HTML。
另一方面,當你指定text
部分時,Nginx不需要發送它自己的主體版本。因此,它只是將您的文本,響應代碼和Content-Type
的值與請求的文件相匹配(請參閱/etc/nginx/mime.types)。
當沒有文件,當你請求一個文件夾或站點根一樣,默認的MIME類型來代替。這種MIME類型是application/octet-stream
,它定義了一些二進制數據。由於大多數瀏覽器都不知道如何渲染隨機二進制數據,所以他們盡其所能,也就是說,他們會顯示自己的硬編碼錯誤頁面。
這就是爲什麼你會得到你所得到的。
現在,如果你想使你的瀏覽器顯示你的foobar
,你需要發送一個合適的Content-Type
。類似plain/text
或plain/html
。通常情況下,這可以使用add_header來完成,但不適用於您的情況,因爲此指令僅適用於有限的響應代碼列表(200,201,204,206,301,302,303,304或307)。
唯一的其他選擇我看到的是重寫你的原始請求的東西熟悉Nginx的,所以它可以使用來自/etc/nginx/mime.types
爲Content-Type
值:
server {
listen 80;
root /app/web;
index index.json;
location/{
rewrite ^.*$ /index.html;
return 409 "foobar";
}
}
這似乎有些違反直覺,但這種將工作。
編輯:
看來,內容類型可以與default_type指令進行設置。所以你可以(也應該)使用default_type text/plain;
而不是rewrite
這條線。
哇謝謝你這個全面的解決方案。我測試了default_type,它工作。謝謝! –