zoukankan      html  css  js  c++  java
  • 记一个nginx server_name配置多个时的坑

    文章转载自:https://blog.csdn.net/u011296355/article/details/106740860/

    背景

    为了区分线上环境和测试环境,我弄了个自己测试专用的域名test.daemoncoder.com,线上环境的正式域名是www.daemoncoder.com。nginx里的server_name配置改为:

    # 只列出了我们关心的配置,省略了其他无关部分
    server {
        server_name www.daemoncoder.com test.daemoncoder.com;
        ...
    }
    

    但是使用时发现请求一直报错,重定向到错误页面,于是开始了问题的定位。

    问题的定位

    根据业务上报错时打的日志,定位到请求公共处理的部分里有这么一个判断:

    if ($_SERVER['SERVER_NAME'] != parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) {
        $this->redirectError();
    }
    

    判断请求referer里解析出的域名如果和nginx里的$server_name变量里的域名如果不一样,就跳到错误页面,也是前面说的问题。

    那么问题来了,看referer中的域名为什么和 $_SERVER['SERVER_NAME'] 不一致呢?我请求用的链接形式如 http://test.daemoncoder.com/xxx 这种形式,但是最终在PHP这一层取到 $_SERVER['SERVER_NAME'] 的值为 www.daemoncoder.com,而 HTTP_REFERER 里的域名为:test.daemoncoder.com。可以看到 SERVER_NAME 的取值和我们的预期不一致,nginx是怎么把这个变量传过来的,需要从 nginx 的 fastcgi_params 配置文件中找一下 SERVER_NAME 的定义:

    fastcgi_param SERVER_NAME $server_name;
    

    可以看到 nginx 里的 $server_name 变量就是我们PHP里取的$_SERVER['SERVER_NAME'] 的来源。

    问题的原因

    通过上面的定位,我们基本可以看到问题的根本原因了(敲黑板,划重点):

    当nginx配置里一个server节点下,server_name配置多个域名时,$server_name变量的值都是配置的第一个。

    再回顾下我的 nginx 配置:

    # 只列出了我们关心的配置,省略了其他无关部分
    server {
        server_name www.daemoncoder.com test.daemoncoder.com;
        ...
    }
    

    server_name 结点有两个:www.daemoncoder.com 和 test.daemoncoder.com,当我用测试域名去访问页面的时候,可以匹配到 test.daemoncoder.com 这个域名,所以会根据当前这个server节点的配置来处理这个请求,但是 nginx 会把$server_name的值设置为当前 server 节点的配置的第一个 server_name,也就是 www.daemoncoder.com。如果配置改为:

    server_name test.daemoncoder.com www.daemoncoder.com;
    

    那么用测试域名请求就可以得到期望的值了(但是正式域名就出问题了)。

    解决方式

    第一种方式就是把配置文件按域名拆分到各自单独的server节点下,也就是:

    # 省略其他无关部分
    server {
        server_name www.daemoncoder.com;
        ...
    }
    server {
        server_name test.daemoncoder.com;
        ...
    }
    

    这样用不同的域名访问会落到各自对应的配置中,解析到的 $server_name 也都是各自的值。

    第二种方式是修改 nginx SERVER_NAME 使用 $host 变量, 也就是把

    fastcgi_param SERVER_NAME $server_name; 修改为:fastcgi_param SERVER_NAME $host;
    

    $host变量的解析都是当前请求的host,不会受 server_name 是否配置多个域名的影响,这样我们在PHP里取 $_SERVER['SERVER_NAME'] 取出的值就是实际请求的域名,也可以解决问题(但是代码里的这个判断逻辑在测试环境似乎就没有意义了,问题不大)。

  • 相关阅读:
    AJAX 三级联动
    AJAX JSON类型返回
    AJAX 汽车详细信息练习
    JQ AJAX
    对话框关联两个Layout时
    删除,拨打电话,发送短信对话框
    自定义对话框,时间日期对话框
    一般对话框,单选复选对话框
    JAVA。String转Int
    加监听器,单选复选按钮
  • 原文地址:https://www.cnblogs.com/sanduzxcvbnm/p/15431912.html
Copyright © 2011-2022 走看看