基于 accept header 的 nginx 错误页面不适用于 json 请求
nginx error pages based on accept header do not work for json requests
我正在尝试构建一个 nginx-based 维护模式应用程序,该应用程序捕获对我的应用程序的所有请求并 return 预定义响应作为 503。
我目前有应用程序请求 json 响应以及用户使用浏览器访问页面。因此,如果请求包含 header Accept: application/json
,我想用 json 文件 maintenance.json
的内容进行响应,否则用 html 文件 maintenance.html
.
我当前的 nginx 配置如下所示:
server {
listen 8080;
root /usr/share/nginx/maintenance;
server_tokens off;
error_page 503 = @unavailable;
location ^~ / {
return 503;
}
location @unavailable {
set $maintenanceContentType text/html;
set $maintenanceFile /maintenance.html;
if ($http_accept = 'application/json') {
set $maintenanceContentType application/json;
set $maintenanceFile /maintenance.json;
}
default_type $maintenanceContentType;
try_files $uri $maintenanceFile;
}
}
对于任何路径的浏览器请求,这都很好:“https://maintenance.my-domain.local/some-path”。我得到响应代码和 html 内容。
但是对于 header Accept: application/json
的请求,我得到一个 404 html 页面。并且 nginx 日志显示 [error] 21#21: *1 open() "/usr/share/nginx/maintenance/some-path" failed (2: No such file or directory), client: 10.244.2.65, server: , request : "GET /asd HTTP/1.1", host: "维护.my-domain.local".
似乎 json 请求出于某种原因忽略了我的 location
。当我删除指令以设置适当的文件并且总是 return html 这也适用于 json-requests.
有人知道吗?
我不一定要为此特定配置寻找修复程序,而是寻找适合我基于 Accept header.
响应不同“错误页面”的需求的东西。
提前致谢!
编辑:出于某种原因,这现在导致 HTTP 200 而不是 503。不知道我更改了什么..
EDIT2:设法修复了其中的一部分:
server {
listen 8080;
root /usr/share/nginx/maintenance;
server_tokens off;
location ^~ / {
if ($http_accept = 'application/json') {
return 503;
}
try_files /maintenance.html =404;
}
error_page 503 /maintenance.json;
location = /maintenance.json {
internal;
}
}
有了这个配置,我现在可以在使用浏览器时获得维护页面,在定义 header Accept: application/json
时获得维护页面 json。虽然现在浏览器响应代码是 200...
好的,我找到了问题的解决方案。
# map the incoming Accept header to a file extension
map $http_accept $accept_ext {
default html;
application/json json;
}
server {
listen 8080;
root /usr/share/nginx/maintenance;
server_tokens off;
# return 503 for all incoming requests
location ^~ / {
return 503;
}
# a 503 redirects to the internal location `@maintenance`. the
# extension of the returned file is decided by the Accept header map
# above (404 in case the file is not found).
error_page 503 @maintenance;
location @maintenance {
internal;
try_files /maintenance.$accept_ext =404;
}
}
关键是上面的地图。我刚刚在那里添加了 application/json
并将其他所有内容默认映射到 html 文件。但是你当然可以在那里添加多个其他 files/file 类型。
我正在尝试构建一个 nginx-based 维护模式应用程序,该应用程序捕获对我的应用程序的所有请求并 return 预定义响应作为 503。
我目前有应用程序请求 json 响应以及用户使用浏览器访问页面。因此,如果请求包含 header Accept: application/json
,我想用 json 文件 maintenance.json
的内容进行响应,否则用 html 文件 maintenance.html
.
我当前的 nginx 配置如下所示:
server {
listen 8080;
root /usr/share/nginx/maintenance;
server_tokens off;
error_page 503 = @unavailable;
location ^~ / {
return 503;
}
location @unavailable {
set $maintenanceContentType text/html;
set $maintenanceFile /maintenance.html;
if ($http_accept = 'application/json') {
set $maintenanceContentType application/json;
set $maintenanceFile /maintenance.json;
}
default_type $maintenanceContentType;
try_files $uri $maintenanceFile;
}
}
对于任何路径的浏览器请求,这都很好:“https://maintenance.my-domain.local/some-path”。我得到响应代码和 html 内容。
但是对于 header Accept: application/json
的请求,我得到一个 404 html 页面。并且 nginx 日志显示 [error] 21#21: *1 open() "/usr/share/nginx/maintenance/some-path" failed (2: No such file or directory), client: 10.244.2.65, server: , request : "GET /asd HTTP/1.1", host: "维护.my-domain.local".
似乎 json 请求出于某种原因忽略了我的 location
。当我删除指令以设置适当的文件并且总是 return html 这也适用于 json-requests.
有人知道吗?
我不一定要为此特定配置寻找修复程序,而是寻找适合我基于 Accept header.
响应不同“错误页面”的需求的东西。提前致谢!
编辑:出于某种原因,这现在导致 HTTP 200 而不是 503。不知道我更改了什么..
EDIT2:设法修复了其中的一部分:
server {
listen 8080;
root /usr/share/nginx/maintenance;
server_tokens off;
location ^~ / {
if ($http_accept = 'application/json') {
return 503;
}
try_files /maintenance.html =404;
}
error_page 503 /maintenance.json;
location = /maintenance.json {
internal;
}
}
有了这个配置,我现在可以在使用浏览器时获得维护页面,在定义 header Accept: application/json
时获得维护页面 json。虽然现在浏览器响应代码是 200...
好的,我找到了问题的解决方案。
# map the incoming Accept header to a file extension
map $http_accept $accept_ext {
default html;
application/json json;
}
server {
listen 8080;
root /usr/share/nginx/maintenance;
server_tokens off;
# return 503 for all incoming requests
location ^~ / {
return 503;
}
# a 503 redirects to the internal location `@maintenance`. the
# extension of the returned file is decided by the Accept header map
# above (404 in case the file is not found).
error_page 503 @maintenance;
location @maintenance {
internal;
try_files /maintenance.$accept_ext =404;
}
}
关键是上面的地图。我刚刚在那里添加了 application/json
并将其他所有内容默认映射到 html 文件。但是你当然可以在那里添加多个其他 files/file 类型。