以下配置对我有用:
server {
listen 80;
root /app/web;
index index.json;
location / {
return 409;
}
}
如果我点击网站,将会显示409页面。但是以下是行不通的:
server {
listen 80;
root /app/web;
index index.json;
location / {
return 409 "foobar";
}
}
页面无法访问。但根据文档http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return
return 409 "foobar";
应该有效。任何想法都错了吗? nginx / error.log中没有日志。
答案 0 :(得分:7)
问题是,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
。
因此,真正的问题是,当返回代码后没有自定义文本时,您的浏览器会显示相当格式化的错误页面,以及灰色&#34;无法访问&#34;一,当存在这样的文本时。
答案是:因为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指令设置Content-Type。因此,您可以(并且应该)使用default_type text/plain;
代替rewrite
行。
答案 1 :(得分:0)
更新@ ivan-tsirulev的答案:
现在,you can set标头,甚至是使用always
的带有错误状态代码的页面。
location @custom_error_page {
return 409 "foobar";
add_header Content-Type text/plain always;
}
但是,如果您设置default_type
,则响应头将具有两个Content-Type头:默认,然后添加。不过,它工作正常。