李贵德 發表於 2025-12-10 11:11:38

Nginx错误拦截转发 error_page的问题解决

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">1. 准备自定义错误页面</a></li><li><a href="#_label1">2. 配置 Nginx 错误页面</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_0">基础配置示例:</a></li></ul><li><a href="#_label2">3. 关键配置说明</a></li><ul class="second_class_ul"></ul><li><a href="#_label3">4. 生效配置</a></li><ul class="second_class_ul"></ul><li><a href="#_label4">5.针对单个特定页面</a></li><ul class="second_class_ul"><li><a href="#_lab2_4_1">1. 假设目标页面为/user/profile(个人资料页)</a></li><li><a href="#_lab2_4_2">2. Nginx 配置示例</a></li><li><a href="#_lab2_4_3">关键配置说明</a></li></ul></ul></div><p>需求:页面未请求成功,需要展示错误的页面,避免卡死提升用户体验感。</p>
<p>在Nginx 中实现 &ldquo;页面路径未请求成功之前展示错误页面&rdquo;,核心是利用 Nginx 的错误页面配置和请求处理机制。通常,当请求的路径不存在(404 错误)或服务器处理失败(如 500 错误)时,Nginx 可以立即返回自定义错误页面。以下是具体实现步骤:</p>
<p class="maodian"><a name="_label0"></a></p><h2>1. 准备自定义错误页面</h2>
<p>首先,创建一个或多个自定义错误页面(如 404.html、500.html),放在 Nginx 可访问的目录下(例如<code>/usr/share/nginx/html/errors/</code>)。示例<code>404.html</code>内容:</p>
<div class="jb51code"><pre class="brush:xhtml;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;页面未找到&lt;/title&gt;
    &lt;meta charset="utf-8"&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;404 - 您请求的页面不存在&lt;/h1&gt;
    &lt;p&gt;正在检查路径,请稍后重试...&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre></div>
<p class="maodian"><a name="_label1"></a></p><h2>2. 配置 Nginx 错误页面</h2>
<p>编辑 Nginx 配置文件(通常是<code>/etc/nginx/nginx.conf</code>或站点配置文件<code>/etc/nginx/conf.d/your_site.conf</code>),添加<code>error_page</code>指令,指定错误码对应的页面路径。</p>
<p class="maodian"><a name="_lab2_1_0"></a></p><h3>基础配置示例:</h3>
<p>nginx.conf</p>
<div class="jb51code"><pre class="brush:bash;">server {
    listen 80;
    server_name your_domain.com;# 替换为你的域名或IP

    # 网站根目录(根据实际情况修改)
    root /usr/share/nginx/html;
    index index.html index.htm;

    # 配置错误页面:当请求失败时返回对应页面
    # 404:路径不存在;500/502/503/504:服务器处理错误
    error_page 404 /errors/404.html;
    error_page 500 502 503 504 /errors/50x.html;

    # 确保错误页面的请求能被正确处理(避免错误页面本身404)
    location /errors/ {
      internal;# 仅允许内部访问,不允许外部直接请求
      root /usr/share/nginx/html;# 错误页面所在的根目录
    }

    # 其他常规配置(如静态文件处理等)
    location / {
      try_files $uri $uri/ =404;# 尝试请求路径,不存在则返回404
      # 访问需登录的页面时,若未登录(401)或权限不足(403),返回错误页
      proxy_intercept_errors on;# 开启后端错误拦截(关键!)
    }
}
</pre></div>
<p>注意:Nginx能处理的状态码有一定范围,v1.24.0版本的仅支持(300-599),若配置完成后Nginx启动失败,可在安装包位置(\nginx-1.24.0\logs\error.log)的日志中查看失败原因。</p>
<p class="maodian"><a name="_label2"></a></p><h2>3. 关键配置说明</h2>
<ul><li>error_page 404 /errors/404.html;:表示当发生 404 错误时,返回/errors/404.html页面。</li><li>internal;:限制错误页面只能被 Nginx 内部调用(避免用户直接访问/errors/404.html)。</li><li>try_files $uri $uri/ =404;:在location /中,Nginx 会先尝试访问请求的文件或目录,若都不存在则触发 404 错误,进而返回自定义页面。</li><li><p>proxy_intercept_errors on;默认情况下,Nginx 会直接将后端返回的 401/403 等错误码转发给客户端。开启该指令后,Nginx 会拦截后端返回的错误码,转而使用error_page配置的自定义页面,实现 &ldquo;请求未完成(验证失败)时展示错误页&rdquo;。</p></li><li><p>针对登录路径的精准拦截若只需对登录接口或需登录的页面生效,可在对应的location块中单独配置proxy_intercept_errors on;,避免全局拦截影响其他正常请求。</p></li></ul>
<p class="maodian"><a name="_label3"></a></p><h2>4. 生效配置</h2>
<p>修改后重启 Nginx 使配置生效:</p>
<p>注意:在任务管理器中搜索nginx,关闭该任务后再重启方能生效。</p>
<div class="jb51code"><pre class="brush:bash;"># 检查配置是否有误
nginx -t

# 重启Nginx
start nginx# 或 在安装包中找到nginx.exe 双击打开开
</pre></div>
<p class="maodian"><a name="_label4"></a></p><h2>5.针对单个特定页面</h2>
<p>如果你只想针对<strong>单个特定页面</strong>(例如&nbsp;<code>/user/profile</code>)配置登录异常的错误页面,需要通过更精确的&nbsp;<code>location</code>&nbsp;匹配规则来实现。核心思路是:仅对目标页面的路径单独设置拦截规则,不影响其他页面。</p>
<p class="maodian"><a name="_lab2_4_1"></a></p><h3>1. 假设目标页面为/user/profile(个人资料页)</h3>
<p>需要确保 Nginx 仅对访问&nbsp;<code>/user/profile</code>&nbsp;时的登录异常(401/403)返回自定义错误页,其他页面不受影响。</p>
<p class="maodian"><a name="_lab2_4_2"></a></p><h3>2. Nginx 配置示例</h3>
<div class="jb51code"><pre class="brush:bash;">server {
    listen 80;
    server_name your_domain.com;

    root /usr/share/nginx/html;
    index index.html;

    # 定义登录异常的错误页面(全局可用,但仅被指定location触发)
    error_page 401 403 /errors/login-error.html;

    # 错误页面的内部访问配置(禁止外部直接访问)
    location /errors/ {
      internal;
      root /usr/share/nginx/html;
    }

    # 仅对单个页面 `/user/profile` 生效的配置
    location = /user/profile {# 注意使用 `=` 精确匹配单个路径
      proxy_pass http://backend_server;# 转发到后端服务
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;

      # 关键:仅在此页面开启错误拦截,触发自定义错误页
      proxy_intercept_errors on;
    }

    # 其他页面的默认配置(不拦截错误,使用后端原生响应)
    location / {
      proxy_pass http://backend_server;
      proxy_set_header Host $host;
      # 这里不配置 proxy_intercept_errors,保持默认行为
    }
}
</pre></div>
<p class="maodian"><a name="_lab2_4_3"></a></p><h3>关键配置说明</h3>
<ol><li><p>location = /user/profile</p>
<ul><li>使用&nbsp;=&nbsp;符号表示精确匹配,仅当请求路径完全等于&nbsp;/user/profile&nbsp;时才生效(不会匹配&nbsp;/user/profile/123&nbsp;等子路径)。</li><li>若需要匹配&nbsp;/user/profile&nbsp;及其子路径(如&nbsp;/user/profile/avatar),可改用&nbsp;location /user/profile(去掉&nbsp;=)。</li></ul></li><li><p>proxy_intercept_errors on;&nbsp;仅在目标&nbsp;location&nbsp;中配置这样只有访问&nbsp;/user/profile&nbsp;时,后端返回的 401/403 错误才会被 Nginx 拦截,并返回自定义的&nbsp;login-error.html;其他页面的错误会按默认逻辑处理(直接返回后端的原始错误响应)。</p></li><li><p>错误页面全局定义,但按需触发error_page 401 403 /errors/login-error.html&nbsp;是全局定义的,但只有开启了&nbsp;proxy_intercept_errors on;&nbsp;的&nbsp;location&nbsp;才会实际使用该错误页,其他路径不影响。</p></li></ol>
<p>注意:以上的配置需要后端小伙伴的积极配合,在转发到后端接口时,后端能够返回相应的状态码,因为Nginx 是反向代理服务器,主要擅长处理&nbsp;HTTP 协议层的逻辑(如状态码、请求头、路径转发等),但对&nbsp;响应体中的业务字段(如 JSON 里的&nbsp;success)&nbsp;处理能力有限(需要借助&nbsp;ngx_http_lua_module&nbsp;等模块编写脚本,复杂度高)。</p>
<p>通过以上配置,Nginx 会在请求路径未找到、服务器错误或超时等 &ldquo;未成功&rdquo; 场景下,立即展示自定义错误页面,提升用户体验。</p>
<p>到此这篇关于Nginx错误拦截转发 error_page的问题解决的文章就介绍到这了,更多相关Nginx错误拦截转发 error_page内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
頁: [1]
查看完整版本: Nginx错误拦截转发 error_page的问题解决