Caddy 配置多端口转发, CORS跨域,Docker部署
编辑
2025-06-09
Linux运维
00

目录

1. 安装 Caddy
2. 配置 Caddy
3. 启动和管理 Caddy
4. 如果需要停止 nginx
5. 如果要Docker部署
Caddy 的优势:
管理命令:
CORS(跨源资源共享)
为什么需要 CORS?
CORS 预检请求(Preflight Request)
什么情况下会触发预检请求?
预检请求的流程
CORS 简单请求 vs. 非简单请求
CORS 相关 HTTP 头
CORS 示例
1. 简单请求(无预检)
2. 非简单请求(触发预检)

1. 安装 Caddy

在 Ubuntu 服务器上执行以下命令:

bash
展开代码
# 安装必要的包 sudo apt update sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https # 添加 Caddy 官方 GPG 密钥 curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg # 添加 Caddy 仓库 curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list # 安装 Caddy sudo apt update sudo apt install caddy

2. 配置 Caddy

bash
展开代码
# 停止默认的 Caddy 服务 sudo systemctl stop caddy # 创建配置目录 sudo mkdir -p /etc/caddy # 将 Caddyfile 上传到服务器 # 将我创建的 Caddyfile 内容复制到 /etc/caddy/Caddyfile sudo nano /etc/caddy/Caddyfile

将上面生成的 Caddyfile 内容复制到这个文件中。

Caddyfile如下:

专门处理 CORS 预检请求 (OPTIONS 方法),设置允许的跨域请求头和方法,Access-Control-Max-Age 1728000 (20天) 表示预检请求的缓存时间,直接返回 204 空响应,符合预检请求规范。

json
展开代码
# 通用端口转发配置模板 :8055, :8056, :8057, :8058, :8059, :8060, :8061, :8062, :8063, :8064, :8065, :8066, :8067, :8068, :8069, :8070 { # 处理 OPTIONS 预检请求 @options method OPTIONS header @options { Access-Control-Allow-Origin * Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE" Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" Access-Control-Max-Age 1728000 } respond @options 204 reverse_proxy 10.150.72.28:{http.request.port} header { Access-Control-Allow-Origin * Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE" Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" Access-Control-Expose-Headers "Content-Length,Content-Range" } }

3. 启动和管理 Caddy

bash
展开代码
# 验证配置文件语法 sudo caddy validate --config /etc/caddy/Caddyfile # 启动 Caddy sudo systemctl start caddy # 设置开机自启 sudo systemctl enable caddy # 查看状态 sudo systemctl status caddy # 查看日志 sudo journalctl -u caddy -f

4. 如果需要停止 nginx

bash
展开代码
# 停止 nginx(避免端口冲突) sudo systemctl stop nginx sudo systemctl disable nginx

5. 如果要Docker部署

写好 docker-compose.yaml , 然后 docker compose up -d

yaml
展开代码
version: '3' # 定义自定义网络 networks: vanblog-network: driver: bridge services: caddy-proxy: image: caddy:latest restart: always ports: - "8055-8070:8055-8070" volumes: - ${PWD}/caddy-proxy/Caddyfile:/etc/caddy/Caddyfile - ${PWD}/caddy-proxy/data:/data - ${PWD}/caddy-proxy/config:/config networks: - vanblog-network environment: TZ: 'Asia/Shanghai'

Caddy 的优势:

  1. 配置简单:语法直观,易于理解
  2. 自动 HTTPS:自动申请和续期 SSL 证书
  3. WebSocket 支持:原生支持,无需额外配置
  4. CORS 处理:简单的 header 指令
  5. 热重载:可以无停机更新配置

管理命令:

bash
展开代码
# 重新加载配置(无停机) sudo caddy reload --config /etc/caddy/Caddyfile # 格式化配置文件 caddy fmt /etc/caddy/Caddyfile --overwrite # 查看配置 caddy list-modules

CORS(跨源资源共享)

CORS(Cross-Origin Resource Sharing,跨源资源共享) 是一种浏览器安全机制,用于控制不同源(Origin)之间的资源访问。

为什么需要 CORS?

  • 浏览器默认遵循同源策略(Same-Origin Policy),即只允许网页从相同协议(HTTP/HTTPS)+ 域名 + 端口加载资源。
  • 如果前端(如 https://example.com)请求后端 API(如 https://api.example.com),由于域名不同,浏览器会阻止请求,除非后端明确允许跨域访问。
  • CORS 允许服务器声明哪些外部源可以访问其资源,从而绕过同源策略的限制。

CORS 预检请求(Preflight Request)

CORS 预检请求(Preflight Request) 是浏览器在发送某些**非简单请求(Non-Simple Request)**之前,先发送一个 OPTIONS 请求,询问服务器是否允许该跨域请求。

什么情况下会触发预检请求?

浏览器在以下情况会先发送 OPTIONS 请求(预检请求):

  1. 使用了非简单 HTTP 方法(如 PUTDELETEPATCH 等)。
  2. 自定义请求头(如 AuthorizationX-Custom-Header)。
  3. Content-Type 不是 application/x-www-form-urlencodedmultipart/form-datatext/plain(如 application/json)。

预检请求的流程

  1. 浏览器发送 OPTIONS 请求,包含:

    • Access-Control-Request-Method:要使用的 HTTP 方法(如 PUT)。
    • Access-Control-Request-Headers:自定义请求头(如 Authorization)。
    • Origin:请求来源(如 https://example.com)。
  2. 服务器响应 OPTIONS 请求,返回:

    • Access-Control-Allow-Origin:允许的源(如 *https://example.com)。
    • Access-Control-Allow-Methods:允许的方法(如 GET, POST, PUT, DELETE)。
    • Access-Control-Allow-Headers:允许的请求头(如 Authorization)。
    • Access-Control-Max-Age:预检请求的缓存时间(如 1728000 秒)。
  3. 如果服务器允许,浏览器才会发送真正的请求(如 PUT /data)。


CORS 简单请求 vs. 非简单请求

类型简单请求(Simple Request)非简单请求(Non-Simple Request)
HTTP 方法GETPOSTHEADPUTDELETEPATCH
请求头仅允许标准头(如 AcceptContent-Type 等)包含自定义头(如 Authorization
Content-Typetext/plainapplication/x-www-form-urlencodedmultipart/form-dataapplication/json
是否需要预检请求❌ 不需要✅ 需要

CORS 相关 HTTP 头

HTTP 头作用
Access-Control-Allow-Origin允许访问的源(如 *https://example.com
Access-Control-Allow-Methods允许的 HTTP 方法(如 GET, POST, PUT, DELETE
Access-Control-Allow-Headers允许的请求头(如 Authorization, Content-Type
Access-Control-Expose-Headers允许前端访问的响应头(如 Content-Length
Access-Control-Max-Age预检请求的缓存时间(如 1728000 秒)
Access-Control-Allow-Credentials是否允许携带 Cookie(如 true

CORS 示例

1. 简单请求(无预检)

http
展开代码
GET /data HTTP/1.1 Host: api.example.com Origin: https://example.com

服务器响应:

http
展开代码
HTTP/1.1 200 OK Access-Control-Allow-Origin: * Content-Type: application/json {"data": "Hello, CORS!"}

2. 非简单请求(触发预检)

预检请求(OPTIONS):

http
展开代码
OPTIONS /data HTTP/1.1 Host: api.example.com Origin: https://example.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: Authorization

服务器响应:

http
展开代码
HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: PUT Access-Control-Allow-Headers: Authorization Access-Control-Max-Age: 1728000

真正的请求(PUT):

http
展开代码
PUT /data HTTP/1.1 Host: api.example.com Origin: https://example.com Authorization: Bearer token123 Content-Type: application/json {"name": "John"}
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!