从零手写实现 nginx-28-error pages 指令

前言

大家好,我是老马。很高兴遇到你。

我们为 java 开发者实现了 java 版本的 nginx

https://github.com/houbb/nginx4j

如果你想知道 servlet 如何处理的,可以参考我的另一个项目:

手写从零实现简易版 tomcat minicat

手写 nginx 系列

如果你对 nginx 原理感兴趣,可以阅读:

从零手写实现 nginx-01-为什么不能有 java 版本的 nginx?

从零手写实现 nginx-02-nginx 的核心能力

从零手写实现 nginx-03-nginx 基于 Netty 实现

从零手写实现 nginx-04-基于 netty http 出入参优化处理

从零手写实现 nginx-05-MIME类型(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型)

从零手写实现 nginx-06-文件夹自动索引

从零手写实现 nginx-07-大文件下载

从零手写实现 nginx-08-范围查询

从零手写实现 nginx-09-文件压缩

从零手写实现 nginx-10-sendfile 零拷贝

从零手写实现 nginx-11-file+range 合并

从零手写实现 nginx-12-keep-alive 连接复用

从零手写实现 nginx-13-nginx.conf 配置文件介绍

从零手写实现 nginx-14-nginx.conf 和 hocon 格式有关系吗?

从零手写实现 nginx-15-nginx.conf 如何通过 java 解析处理?

从零手写实现 nginx-16-nginx 支持配置多个 server

从零手写实现 nginx-17-nginx 默认配置优化

从零手写实现 nginx-18-nginx 请求头+响应头操作

从零手写实现 nginx-19-nginx cors

从零手写实现 nginx-20-nginx 占位符 placeholder

从零手写实现 nginx-21-nginx modules 模块信息概览

从零手写实现 nginx-22-nginx modules 分模块加载优化

从零手写实现 nginx-23-nginx cookie 的操作处理

从零手写实现 nginx-24-nginx IF 指令

从零手写实现 nginx-25-nginx map 指令

从零手写实现 nginx-26-nginx rewrite 指令

从零手写实现 nginx-27-nginx return 指令

从零手写实现 nginx-28-nginx error_pages 指令

从零手写实现 nginx-29-nginx try_files 指令

nginx 的 error_page 指令

nginxerror_page 指令用于定义自定义错误页面。

当服务器遇到错误时,nginx 会根据配置返回自定义的错误页面,而不是默认的错误页面。这在提高用户体验和品牌一致性方面非常有用。

error_page 指令语法

error_page code [code ...] [=[response]] uri;
  • code:HTTP 状态码,可以是单个状态码或多个状态码,表示哪些错误状态码会触发自定义错误页面。
  • =[response]:可选参数,表示在返回自定义错误页面时,是否改变 HTTP 响应状态码。
  • uri:指定自定义错误页面的 URI,可以是相对路径或绝对路径。

示例和解释

基本用法
  1. 单个错误代码
error_page 404 /custom_404.html;

当服务器返回 404 错误时,nginx 会返回 /custom_404.html 这个页面。

  1. 多个错误代码
error_page 500 502 503 504 /custom_5xx.html;

当服务器返回 500, 502, 503 或 504 错误时,nginx 会返回 /custom_5xx.html 这个页面。

改变响应状态码

有时,你可能希望在重定向到自定义错误页面时,改变 HTTP 响应状态码。例如,将 404 错误重定向到一个页面,但返回 200 状态码。

error_page 404 =200 /custom_404.html;

当服务器返回 404 错误时,nginx 会返回 /custom_404.html 页面,但 HTTP 响应状态码是 200。

使用内部重定向

可以使用 @named_location 来处理错误。这个方法允许你将错误处理逻辑封装在一个内部位置。

error_page 500 502 503 504 /50x.html;location = /50x.html {root /usr/share/nginx/html;
}

当服务器返回 500, 502, 503 或 504 错误时,nginx 会将请求内部重定向到 /50x.html。此时,/50x.html 页面存放在 /usr/share/nginx/html 目录下。

高级用法

自定义错误页面与代理服务器结合

当你使用 nginx 作为反向代理服务器时,也可以定义自定义错误页面。例如,当后端服务器不可用时,显示友好的错误页面。

server {listen 80;server_name example.com;location / {proxy_pass http://backend;proxy_intercept_errors on;error_page 500 502 503 504 /custom_50x.html;}location = /custom_50x.html {root /usr/share/nginx/html;}
}

在这个例子中,当后端服务器返回 500, 502, 503 或 504 错误时,nginx 会拦截这些错误并返回自定义的 /custom_50x.html 页面。

常见错误代码

以下是一些常见的 HTTP 错误代码及其含义:

  • 400:Bad Request(错误请求)
  • 401:Unauthorized(未授权)
  • 403:Forbidden(禁止访问)
  • 404:Not Found(未找到)
  • 500:Internal Server Error(内部服务器错误)
  • 502:Bad Gateway(错误网关)
  • 503:Service Unavailable(服务不可用)
  • 504:Gateway Timeout(网关超时)

示例:完整的 Nginx 配置文件

server {listen 80;server_name example.com;location / {try_files $uri $uri/ =404;}error_page 404 /custom_404.html;error_page 500 502 503 504 /custom_50x.html;location = /custom_404.html {root /usr/share/nginx/html;}location = /custom_50x.html {root /usr/share/nginx/html;}
}

结论

nginxerror_page 指令非常灵活,允许你根据需要自定义错误页面,以改善用户体验和提供更友好的错误消息。

通过使用该指令,你可以轻松地创建品牌一致的错误页面,并将其集成到现有的 nginx 配置中。

java error_page

error_page 指令的处理

package com.github.houbb.nginx4j.config.param.impl.dispatch;import com.github.houbb.heaven.util.util.CollectionUtil;
import com.github.houbb.log.integration.core.Log;
import com.github.houbb.log.integration.core.LogFactory;
import com.github.houbb.nginx4j.config.NginxCommonConfigEntry;
import com.github.houbb.nginx4j.config.NginxConfig;
import com.github.houbb.nginx4j.config.param.AbstractNginxParamLifecycleDispatch;
import com.github.houbb.nginx4j.exception.Nginx4jException;
import com.github.houbb.nginx4j.support.errorpage.INginxErrorPageManage;
import com.github.houbb.nginx4j.support.request.dispatch.NginxRequestDispatchContext;import java.util.List;/*** 参数处理类 响应头处理** @since 0.25.0* @author 老马啸西风*/
public class NginxParamHandleErrorPage extends AbstractNginxParamLifecycleDispatch {private static final Log logger = LogFactory.getLog(NginxParamHandleErrorPage.class);@Overridepublic boolean doBeforeDispatch(NginxCommonConfigEntry configParam, NginxRequestDispatchContext context) {List<String> values = configParam.getValues();if(CollectionUtil.isEmpty(values) || values.size() < 2) {throw new Nginx4jException("error_page 必须包含2个参数");}NginxConfig nginxConfig = context.getNginxConfig();INginxErrorPageManage nginxErrorPageManage = nginxConfig.getNginxErrorPageManage();// 直接拆分String lastHtml = values.get(values.size()-1);for(int i = 0; i < values.size()-1; i++) {String code = values.get(i);nginxErrorPageManage.register(code, lastHtml);}return true;}@Overridepublic boolean doAfterDispatch(NginxCommonConfigEntry configParam, NginxRequestDispatchContext context) {return true;}@Overrideprotected String getKey(NginxCommonConfigEntry configParam, NginxRequestDispatchContext context) {return "error_page";}@Overridepublic String directiveName() {return "error_page";}}

定义 error_page 映射关系的存储

package com.github.houbb.nginx4j.support.errorpage;import com.github.houbb.log.integration.core.Log;
import com.github.houbb.log.integration.core.LogFactory;import java.util.HashMap;
import java.util.Map;/*** @since 0.25.0* @author 老马啸西风*/
public class NginxErrorPageManageDefault implements INginxErrorPageManage {private static final Log logger = LogFactory.getLog(NginxErrorPageManageDefault.class);private final Map<String, String> map = new HashMap<>();@Overridepublic void register(String code, String htmlPath) {map.put(code, htmlPath);logger.info("error_page register code={}, path={}", code, htmlPath);}@Overridepublic String getPath(String code) {String path = map.get(code);logger.info("error_page register code={}, path={}", code, path);return path;}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/45097.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

夹子音转换器matlab

操作过程点击此处观看 上段时间补习了一下傅里叶变化的知识&#xff0c;突发奇想可以根据此做一款声音转换器&#xff0c;使用工科神器Matlab进行完成&#xff0c;并且开发了可操作界面如下图所示&#xff1a; 功能实现与描述 软件中可以实现声音的录制、回放、文件的保存与…

【C++】动态内存分配(关于构造与析构函数的调用)动态数组类 动态创建多维数组 知识点+代码学习记录

一.动态内存分配相关知识点 1.堆和栈内存&#xff1a; 堆内存&#xff1a;动态分配的内存位于堆中&#xff0c;它不受作用域限制&#xff0c;由程序员控制其生命周期。 栈内存&#xff1a;局部变量和函数参数等自动分配的内存位于栈中&#xff0c;由编译器自动管理。 2.new…

性能测试(2)

jmeter参数化 loadrunner Jmeter IP欺骗&#xff0c;也称为IP欺诈&#xff0c;是指通过伪装、篡改IP地址的方式&#xff0c;进行网络攻击或欺骗行为。这种行为可能会导致网络安全问题&#xff0c;包括身份盗窃、数据泄露、DDoS攻击等。为了保护自己的网络安全&#xff0c;用户…

MySQL-表的约束

文章目录 一、空属性二、默认值三、zerofill四、列描述五、主键删除主键追加主键复合主键根据主键快速索引 六、自增长last_insert_id() 七、唯一键八、外键class表&#xff08;主表&#xff09;student表&#xff08;从表&#xff09; 一、空属性 之前我们将表的机构&#xff…

单例模式java

并发的有序性会导致返回空指针 class A{private static volatil A a;private A(){}public A getInstance(){if(anull){synchronized(A.class){if(anull)anew A();}}return a; }anew A();这条语句&#xff0c;他需要&#xff1a;开辟空间&#xff0c;初始化空间&#xff0c;指针…

python热门面试题三

面试题1&#xff1a;Python中的列表推导式是什么&#xff1f;请给出一个例子。 回答&#xff1a; 列表推导式&#xff08;List Comprehension&#xff09;是Python中一种非常强大且简洁的构建列表的工具。它允许你通过一个表达式来创建一个新的列表&#xff0c;这个表达式定义…

无显卡也可以玩大模型-MiniGPT-4篇

MiniGPT-4学习 1.Colab上部署MiniGPT-42.论文摘要3.模型架构4.模型训练5.总结 1.Colab上部署MiniGPT-4 代码&#xff1a; https://github.com/Czi24/Awesome-MLLM-LLM-Colab/blob/master/MLLM/MiniGPT-4-colab/MiniGPT-4.md 2.论文摘要 最近的 GPT-4 展示了非凡的多模式能力&…

【设计模式之美】【建造型】工厂模式:通过面向接口编程思路,串起业务流程

文章目录 一. 简单工厂&#xff08;Simple Factory&#xff09;第一种简单工厂&#xff1a;面向接口编程与工厂类&#xff1a;划分功能职责第二种&#xff1a;单例简单工厂&#xff1a;节省内存和对象创建的时间 二. 工厂方法&#xff08;Factory Method&#xff09;&#xff1…

文心一言:如何备考软考架构师

提问&#xff1a;软考高级:架构师指导&#xff0c;有哪些考点、重点考点有哪些&#xff1f;需要如何备考&#xff1f;案例分析题如何做&#xff1f;论文如何写&#xff1f; 文心一言回答1700字如下&#xff1a; 针对软考高级架构师的考试&#xff0c;以下是对考点、重点考点、备…

DiffusionModel-Transformer知识回顾

论文链接&#xff1a; Attention Is All You Need CNN vs RNN vs Transformer CNN&#xff08;卷积神经网络&#xff09; 特点&#xff1a; 局部连接&#xff1a;每个卷积神经元只与输入数据的局部区域连接&#xff0c;这有助于捕捉局部特征。权重共享&#xff1a;卷积核的权重…

Android笔记:Constructor (xxx) has been changed after generation.

遇到此报错时&#xff0c;onstructor (xxx) has been changed after generation.是因为修改了实体类字段后什么都不修改的话就会报这个错 这条信息是关于代码生成和代码变更的警告。当你使用某些工具&#xff08;如注解处理器、代码生成库等&#xff09;来自动生成代码时&…

运行在Linux上的程序越来越慢的排查思路

1、通过free -h 排查内存使用情况&#xff0c;是否内存满了 2、通过df -h 排查磁盘的使用情况&#xff0c;磁盘是否没有空间了 3、检查系统资源配置情况&#xff0c;比如使用ulimit -a检查当前会话的资源限制&#xff0c;如最大文件数、打开文件描述符数等&#xff0c;看是否…

清华计算几何-ConvexHull(凸包)-求极点InTriangle/ToLeft Test

ConvexHull(凸包) 凸包是什么 凸包是计算几何一个非常基础核心的概念。我理解的凸包就是给定一个点集合, 最外围的点的包围体就是凸包。如下所示: 极点(ExtremityPoint) 给定的点集合中, 如果一个点存在一条直线, 让其他所有点都在于该直线的同一侧, 则该点为极点。 非极点 …

如何理解electron 的预加载脚本

在 Electron 应用中,预加载脚本(Preload Script)是一个非常重要的概念,它允许你在渲染进程(web 页面)和主进程之间创建一个安全的桥梁。预加载脚本运行在 Node.js 环境中,但位于渲染进程的一个单独的上下文中,这意味着它可以访问 Node.js 的 API,但无法直接访问 DOM。…

JavaScript进阶(7) ----构造函数和原型对象

目录 构造函数 prototype 定义&#xff1a; 使用场景&#xff1a; constructor 使用场景&#xff1a; 原型proto 原型链 定义 特点 instanceof 运算符 原型继承的基本概念 在JavaScript中&#xff0c;构造函数和原型是面向对象编程的核心概念&#xff0c;它们共同构…

海康工业相机驱动

1.新建基于对话框的MFC程序&#xff0c;界面布局如下 2.修改控件ID&#xff0c;为控件绑定变量 3.创建全局变量&#xff0c;构造函数中初始化变量&#xff0c;初始化对话框界面&#xff0c;补齐各控件按钮响应函数 全文程序如下&#xff1a; // MFC_GrabimageDlg.h : 头文件 /…

【动态规划Ⅰ】斐波那契、爬楼梯、杨辉三角

动态规划—斐波那契系列 什么是动态规划斐波那契数组相关题目509. 斐波那契数 Easy1137. 第 N 个泰波那契数 Easy 杨辉三角118. 杨辉三角 Easy 爬楼梯相关题目70. 爬楼梯 Easy746. 使用最小花费爬楼梯 Easy 什么是动态规划 动态规划是一种通过将原问题分解为相对简单的子问题来…

linux下解压命令

在Linux下&#xff0c;解压缩文件通常涉及多种命令&#xff0c;具体取决于文件的压缩格式。以下是一些常用的解压缩命令&#xff1a; tar.gz / .tgz 如果文件扩展名为 .tar.gz 或 .tgz&#xff0c;你可以使用 tar 命令来解压缩&#xff1a; tar -xzf filename.tar.gz这里的 -x …

近期几首小诗汇总-生活~卷

生活 为生活飘零&#xff0c;风雨都不阻 路见盲人艰&#xff0c;为她心点灯 贺中科大家长论坛成立十五周年 科学家园有喜贺 园外丑汉翘望中 曾一学子入我科 正育科二盼长大 憧憬也能入此家 与科学家论短长 园外翘首听高论 发现有隙入此坛 竟然也能注册成 入园浏览惶然立 此贴…

系统架构的基础:定义、原则与发展历程

目录 1. 系统架构的定义 2. 系统架构的基本组成部分 2.1 架构层次 2.2 架构视图 2.3 架构原则 3. 系统架构的发展历程 3.1 初期阶段:单体架构(Monolithic Architecture) 3.2 面向对象和组件化阶段 3.3 客户端-服务器架构(Client-Server Architecture) 3.4 三层架…