Nginx 跨域请求支持多域名的“通关秘籍”

在 Nginx 中配置跨域请求支持多域名的技巧与实践

当我们想让 Nginx 支持多个域名跨域时,关键在于告诉 Nginx:“嘿,当这些特定域名来请求资源时,请给它们开绿灯!”

实现这个目标,我们主要利用 Nginx 的 map 指令和 $http_origin 变量。

$http_origin 能获取到请求来自哪个源(域名),而 map 则可以根据这个源,动态地设置 Access-Control-Allow-Origin 的值。

定义你的“白名单”域名

首先,我们需要在 Nginx 的 http 配置块中,创建一个“白名单”列表。这个列表里放的就是你允许跨域访问的那些域名。

http {
    # ... 其他配置 ...

    # 定义一个变量 $cors_origin,默认值为 0
    map $http_origin $cors_origin {
        default 0;
        "http://www.a.com" 1;
        "https://www.b.com" 1;
        "http://localhost:8080" 1;
    }

    # ... 其他配置 ...
}

配置说明:

  • map $http_origin $cors_origin { ... }: 这就像建立一个对应关系。$http_origin 是请求来的域名,$cors_origin 是我们自定义的一个变量。
  • default 0;: 如果请求的域名不在我们的白名单里,$cors_origin 的值就是 0
  • "http://www.a.com" 1;: 如果请求来自 http://www.a.com,那么 $cors_origin 的值就是 1。这里你可以添加任意多个你想要支持的域名。

在你的 server 配置中“智能”放行

接下来,在你需要处理跨域请求的 server 配置块中(通常是 location 块),我们要根据 $cors_origin 的值来决定是否给请求“盖章放行”。

server {
    # ... 其他配置 ...

    location / {
        # 如果 $cors_origin 是 1,就把请求的源域名赋值给 $cors_origin
        if ($cors_origin = '1') {
            set $cors_origin $http_origin;
        }

        # 允许指定的域名访问
        add_header Access-Control-Allow-Origin "$cors_origin";
        # 允许携带 Cookie
        add_header Access-Control-Allow-Credentials "true";
        # 允许的请求方法
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
        # 允许的请求头
        add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";

        # 针对 OPTIONS 预检请求的处理
        if ($request_method = 'OPTIONS') {
            return 204;
        }
    }

    # ... 其他配置 ...
}

配置说明:

  • if ($cors_origin = '1') { set $cors_origin $http_origin; }: 这是一个判断。如果 $cors_origin 的值是我们之前设定的 1(意味着这个域名在白名单里),那么我们就把当前请求的域名($http_origin)赋值给 $cors_origin 变量。
  • add_header Access-Control-Allow-Origin "$cors_origin";: 这就是最关键的一步!它会把处理后的 $cors_origin 变量的值(也就是白名单里的那个域名)添加到响应头里,告诉浏览器:“这个域名是自己人,可以访问!” 如果请求的域名不在白名单里,$cors_origin 的值就是 0,浏览器就会拒绝这个跨域请求。

重新加载 Nginx 配置

最后一步,别忘了让 Nginx 加载你最新的配置!

nginx -t  # 检查配置语法是否正确
nginx -s reload # 重新加载配置

搞定!现在你的 Nginx 就可以愉快地支持多个域名跨域啦!

Licensed under CC BY-NC-SA 4.0