nginx笔记

请求方法

HTTP协议定义了多种请求方法,每种方法都有特定的语义和用途

主要请求方法

  • POST方法:主要用于向服务器提交数据,常用来执行新增或修改操作。POST请求的参数包含在请求体中而非URL中,这使得它可以传输较大量的数据,并且支持多种编码格式。典型的应用场景包括提交用户注册信息、上传文件等。

  • OPTIONS方法:用于获取目标资源所支持的通信选项,即服务器支持哪些HTTP方法。它在跨域资源共享(CORS)中扮演重要角色,浏览器会先发送OPTIONS请求进行预检,以确认实际请求(如POST)是否被允许。

  • GET‌:用于请求指定的资源,通常用于查询数据而不会修改资源内容。无论进行多少次操作,结果都是一样的,具有幂等性。

  • PUT‌:向服务器发送数据以更新资源,它会替换指定资源的全部内容。与POST不同,PUT是幂等的,多次发出相同的PUT请求会产生相同的结果。

  • DELETE‌:用于请求服务器删除指定的资源。

  • HEAD‌:类似于GET请求,但服务器只返回响应头,不返回响应体,常用于检查资源是否存在或获取资源的元数据。

  • PATCH‌:用于更新资源的部分内容,与PUT不同,它只发送描述更改的文档而不是整个资源。

  • CONNECT‌:用于建立到服务器的隧道连接,主要用于通过HTTP代理服务器建立SSL/TLS连接。

  • TRACE‌:用于回显服务器收到的请求,主要用于调试和诊断目的。

方法特性对比

不同的HTTP方法在幂等性方面存在差异:GET、PUT、DELETE、HEAD、OPTIONS和TRACE都是幂等的,而POST和PATCH不是幂等的。

在实际开发中,虽然GET和POST最为常用,但在构建RESTful API或处理特定类型的交互时,了解其他方法也至关重要。例如,OPTIONS方法常用于跨域资源共享(CORS)预检请求,以确定服务器是否允许特定类型的跨域请求。

跨域配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
set $allow_origin "";
# 使用严格规范的正则匹配
if ($http_origin ~* "^https://(xxxxx\.cn|[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.xxxxx\.cn)$") {
set $allow_origin $http_origin;
}

# 处理OPTIONS请求
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $allow_origin always;
add_header 'Access-Control-Allow-Methods' 'POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type' always;
add_header 'Access-Control-Max-Age' 1728000 always;
return 204;
}

# 处理正常请求
add_header 'Access-Control-Allow-Origin' $allow_origin always;
add_header 'Access-Control-Allow-Methods' 'POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type' always;

$http_origin 为空时的情况

$http_origin 为空通常有两种场景:

  1. 同域请求:客户端与服务器域名相同(如客户端 https://goupos.cn 向服务器 https://goupos.cn 发起请求),浏览器不会发送 Origin 头,因此 $http_origin 为空。
  2. 非跨域的简单请求:某些情况下(如 GET 请求不带自定义头),浏览器可能不发送 Origin 头,导致 $http_origin 为空。

在你的配置中,$http_origin 为空时的表现:

  • 不会进入 if ($http_origin ~* "...") 条件块,因此 $allow_origin 保持初始值 ""(空)。
  • 对于同域请求:浏览器因 “同源策略” 允许请求通过,即使 Access-Control-Allow-Origin 为空(跨域头仅对跨域请求生效),请求正常执行。
  • 对于非跨域但触发预检的请求(极少情况):若同域请求因带自定义头触发 OPTIONS 预检,会因 Access-Control-Allow-Origin 为空被浏览器拦截(实际中同域很少触发预检)。

用于处理浏览器的跨域资源共享(CORS)预检请求(OPTIONS 请求),核心作用是告诉浏览器:“允许哪些跨域请求是被允许的”,从而让后续的实际请求(如 GET)能正常执行。以下是具体含义和允许的操作:

  1. set $allow_origin "";
  • 初始化变量 $allow_origin 为空字符串,默认拒绝所有跨域来源(“默认不允许” 是安全原则)。

  1. if ($http_origin ~* "...") { ... }

    • 作用:校验客户端的来源域名($http_origin)是否在白名单内。
      正则 ^https://(XXXXXX\.cn|[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.XXXXXX\.cn)$:
      仅匹配 https://XXXXXX.cn(主域名)或 https://xxx.XXXXXX.cn(符合规范的子域,如 www.XXXXXX.cnapi-test.XXXXXX.cn)。
      匹配成功时:set $allow_origin $http_origin 将允许的来源设为客户端实际域名(动态允许白名单内的跨域)。
  2. if ($request_method = 'OPTIONS') { ... }

    • 作用:处理浏览器的跨域预检请求(OPTIONS 方法),告知浏览器是否允许后续的实际请求(如 POST)。

    • 用于处理浏览器的跨域资源共享(CORS)预检请求(OPTIONS 请求),核心作用是告诉浏览器:“允许哪些跨域请求是被允许的”,从而让后续的实际请求(如 GET)能正常执行。以下是具体含义和允许的操作:

    • 含义:当客户端发送的请求方法是OPTIONS时,执行花括号内的逻辑。

    • 背景:浏览器在处理跨域的复杂请求(如带自定义头、非简单方法的请求)时,会先自动发送一个OPTIONS请求(预检请求),询问服务器 “是否允许后续的实际请求”。只有预检通过后,浏览器才会发送真正的请求(如 GET)。

  3. add_header 'Access-Control-Allow-Origin' $allow_origin always;

    • 含义:允许 “发起请求的域名” 跨域访问服务器。
    • 细节:
      • $http_origin是 Nginx 的内置变量,代表客户端的来源域名(如https://client.com)。
      • always确保这个头在所有状态码的响应中都生效(避免遗漏)。
    • 允许的操作:仅允许 “实际发起请求的域名” 跨域,拒绝其他未请求的域名(比*更安全)。
  4. add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;

    • 含义:告诉浏览器,服务器允许的跨域请求方法是GETOPTIONS
    • 允许的操作:客户端后续只能用GET方法发起跨域请求(OPTIONS是预检本身,不算实际请求),其他方法(如 POST、PUT)会被浏览器拦截。
  5. add_header 'Access-Control-Allow-Headers' 'Content-Type' always;

    • 含义:告诉浏览器,服务器允许跨域请求中携带Content-Type这个请求头。
    • 允许的操作:客户端在跨域请求中可以指定Content-Type(如application/json),服务器会接受该头信息,否则浏览器会因 “携带了不允许的头” 而拦截请求。
  6. add_header 'Access-Control-Max-Age' 1728000 always;

    • 含义:指定预检请求的结果(即上述允许规则)可以被浏览器缓存1728000 秒(20 天)
    • 允许的操作:缓存期间,相同的跨域请求不会重复发送预检请求,减少服务器压力和网络开销。
  • return 204:预检请求无需返回内容,用 204 No Content 快速响应。

安装nginx最新版本

查看版本信息

1
lsb_release  -a

备份配置

1
2
# 备份整个Nginx配置目录(防止配置丢失)
sudo cp -r /etc/nginx /etc/nginx.bak-$(date +%Y%m%d)

移除 Ubuntu 默认 Nginx(保留配置)

1
2
# 仅删除程序文件,保留/etc/nginx配置(--purge会删配置,绝对不用)
sudo apt remove -y nginx nginx-core nginx-common
1
2
3
4
5
6
7
8
# 1. 先更新APT缓存(获取最新的包信息)
sudo apt update
# 2. 执行全量升级(-y 表示自动确认升级)
sudo apt upgrade -y
# 执行完整升级,处理所有待升级包(包括之前kept back的)
sudo apt full-upgrade -y
sudo apt autoremove -y # 移除不再需要的依赖包
sudo apt clean # 清理APT缓存的旧包文件

更换 Nginx 官方源并更新的完整操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 首先备份当前的源列表(防止出错)
sudo cp /etc/apt/sources.list.d/nginx.list /etc/apt/sources.list.d/nginx.list.bak 2>/dev/null

# 2. 安装必要的依赖(用于验证源的合法性)
sudo apt update && sudo apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring

# 3. 导入Nginx官方GPG密钥
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-official.gpg >/dev/null

# 4. 配置Nginx官方源(根据Ubuntu版本选择,这里以22.04为例,jammy是22.04的代号)
# 若你是20.04,将jammy替换为focal;18.04替换为bionic
Ubuntu 18.04 → bionic
Ubuntu 20.04 → focal
Ubuntu 22.04 → jammy
Ubuntu 24.04 → noble

下面两个配置是示例:四选一就可以了,可以通过lsb_release -a命令查看版本,然后根据自己版本修改下面参数

**创建Nginx官方源独立配置文件(/etc/apt/sources.list.d/nginx-official.list)如下的版本是22.04 **

1
2
3
4
sudo tee /etc/apt/sources.list.d/nginx-official.list << 'EOF'
# Nginx官方稳定版源(仅用于Nginx更新,独立配置)
deb [signed-by=/usr/share/keyrings/nginx-official.gpg] http://nginx.org/packages/ubuntu/ jammy nginx
EOF

版本18.04

1
2
3
4
sudo tee /etc/apt/sources.list.d/nginx-official.list << 'EOF'
# Nginx官方稳定版源(仅用于Nginx更新,独立配置)
deb [signed-by=/usr/share/keyrings/nginx-official.gpg] http://nginx.org/packages/ubuntu/ bionic nginx
EOF

版本20.04

1
2
3
4
sudo tee /etc/apt/sources.list.d/nginx-official.list << 'EOF'
# Nginx官方稳定版源(仅用于Nginx更新,独立配置)
deb [signed-by=/usr/share/keyrings/nginx-official.gpg] http://nginx.org/packages/ubuntu/ focal nginx
EOF

版本 24.04

1
2
3
4
sudo tee /etc/apt/sources.list.d/nginx-official.list << 'EOF'
# Nginx官方稳定版源(仅用于Nginx更新,独立配置)
deb [signed-by=/usr/share/keyrings/nginx-official.gpg] http://nginx.org/packages/ubuntu/ noble nginx
EOF
1
2
3
4
5
6
7
# 5. 设置源优先级(确保优先使用Nginx官方源,优先级1001高于系统源)
sudo tee /etc/apt/preferences.d/nginx-official-priority << 'EOF'
# 仅对nginx相关包生效,避免影响其他软件
Package: nginx*
Pin: origin nginx.org
Pin-Priority: 1001
EOF
1
2
3
4
5
6
7
8
# 6. 更新软件源并升级Nginx 更新源缓存(仅读取Nginx独立配置,无冲突)
sudo apt update

# 安装官方最新稳定版
sudo apt upgrade -y nginx

# 7. 验证Nginx版本
nginx -v

配置 Nginx 自动更新(独立配置文件)

创建/etc/apt/apt.conf.d/60-nginx-auto-upgrade,仅自动更新 Nginx,不影响系统其他包:

对于不同版本:

1
2
3
4
Ubuntu 18.04 → bionic
Ubuntu 20.04 → focal
Ubuntu 22.04 → jammy
Ubuntu 24.04 → noble

18.04

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 创建自动更新规则文件(仅更新Nginx,不影响系统其他包)
sudo tee /etc/apt/apt.conf.d/60-nginx-auto-upgrade << 'EOF'
# Nginx独立自动更新配置(Ubuntu 18.04 noble)
Unattended-Upgrade::Allowed-Origins {
"nginx.org:bionic"; # 适配18.04代号
};
# 仅白名单Nginx相关包,避免误更其他软件
Unattended-Upgrade::Package-Whitelist {
"^nginx$";
"^nginx-core$";
"^nginx-common$";
};
# 更新后验证配置并重启Nginx(配置错误则不重启)
Unattended-Upgrade::Post-Invoke {
"nginx -t && systemctl restart nginx || echo 'Nginx配置错误,未重启'";
};
EOF

# 启用自动更新服务(24.04默认已安装,只需启用)
sudo systemctl enable --now unattended-upgrades

20.04

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 创建自动更新规则文件(仅更新Nginx,不影响系统其他包)
sudo tee /etc/apt/apt.conf.d/60-nginx-auto-upgrade << 'EOF'
# Nginx独立自动更新配置(Ubuntu 20.04 noble)
Unattended-Upgrade::Allowed-Origins {
"nginx.org:focal"; # 适配20.04代号
};
# 仅白名单Nginx相关包,避免误更其他软件
Unattended-Upgrade::Package-Whitelist {
"^nginx$";
"^nginx-core$";
"^nginx-common$";
};
# 更新后验证配置并重启Nginx(配置错误则不重启)
Unattended-Upgrade::Post-Invoke {
"nginx -t && systemctl restart nginx || echo 'Nginx配置错误,未重启'";
};
EOF

# 启用自动更新服务(24.04默认已安装,只需启用)
sudo systemctl enable --now unattended-upgrades

22.04

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 创建自动更新规则文件(仅更新Nginx,不影响系统其他包)
sudo tee /etc/apt/apt.conf.d/60-nginx-auto-upgrade << 'EOF'
# Nginx独立自动更新配置(Ubuntu 22.04 noble)
Unattended-Upgrade::Allowed-Origins {
"nginx.org:jammy"; # 适配22.04代号
};
# 仅白名单Nginx相关包,避免误更其他软件
Unattended-Upgrade::Package-Whitelist {
"^nginx$";
"^nginx-core$";
"^nginx-common$";
};
# 更新后验证配置并重启Nginx(配置错误则不重启)
Unattended-Upgrade::Post-Invoke {
"nginx -t && systemctl restart nginx || echo 'Nginx配置错误,未重启'";
};
EOF

# 启用自动更新服务(24.04默认已安装,只需启用)
sudo systemctl enable --now unattended-upgrades

24.04

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 创建自动更新规则文件(仅更新Nginx,不影响系统其他包)
sudo tee /etc/apt/apt.conf.d/60-nginx-auto-upgrade << 'EOF'
# Nginx独立自动更新配置(Ubuntu 24.04 noble)
Unattended-Upgrade::Allowed-Origins {
"nginx.org:noble"; # 适配24.04代号
};
# 仅白名单Nginx相关包,避免误更其他软件
Unattended-Upgrade::Package-Whitelist {
"^nginx$";
"^nginx-core$";
"^nginx-common$";
};
# 更新后验证配置并重启Nginx(配置错误则不重启)
Unattended-Upgrade::Post-Invoke {
"nginx -t && systemctl restart nginx || echo 'Nginx配置错误,未重启'";
};
EOF

# 启用自动更新服务(24.04默认已安装,只需启用)
sudo systemctl enable --now unattended-upgrades

创建一键手动更新脚本(备用)

创建/usr/local/bin/update-nginx脚本,执行即可更新到最新版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 编写一键更新脚本,包含验证+重启逻辑
sudo tee /usr/local/bin/update-nginx << 'EOF'
#!/bin/bash
# Nginx一键更新脚本(Ubuntu 24.04 noble专用)
set -e
echo "=== 1. 更新Nginx官方源缓存 ==="
sudo apt update -o Dir::Etc::sourcelist="sources.list.d/nginx-official.list"

echo "=== 2. 升级Nginx到官方最新版 ==="
sudo apt upgrade -y nginx

echo "=== 3. 验证Nginx版本 ==="
nginx -v

echo "=== 4. 检查Nginx配置语法 ==="
nginx -t

echo "=== 5. 重启Nginx(配置正常则执行) ==="
if nginx -t; then
sudo systemctl restart nginx
echo "✅ Nginx已更新到最新版并重启成功!"
else
echo "❌ 配置语法错误,未重启Nginx,请检查/etc/nginx配置!"
exit 1
fi
EOF

# 赋予脚本执行权限
sudo chmod +x /usr/local/bin/update-nginx

使用方法(更新 Nginx 到最新版)

自动更新(无需手动操作)

配置完成后,系统会每天自动检查 Nginx 官方源的更新,发现新版本会自动下载、安装,并在配置语法正常的情况下重启 Nginx。

手动更新(主动升级)

只需执行一行命令,即可一键完成更新 + 验证 + 重启:

1
update-nginx

验证自动更新规则(可选)

1
sudo unattended-upgrade --dry-run --debug | grep nginx

故障回滚(若更新后异常)

1
2
3
4
5
6
7
8
# 恢复备份配置
sudo cp -r /etc/nginx.bak-YYYYMMDD/* /etc/nginx/

# 验证配置并重启
sudo nginx -t && systemctl restart nginx

# 查看Nginx状态
systemctl status nginx