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'] 取出的值就是实际请求的域名,也可以解决问题(但是代码里的这个判断逻辑在测试环境似乎就没有意义了,问题不大)。

  • 相关阅读:
    苹果一体机发射Wi-Fi
    iphone 屏蔽系统自动更新,消除设置上的小红点
    data parameter is nil 异常处理
    copy与mutableCopy的区别总结
    java axis2 webservice
    mysql 远程 ip访问
    mysql 存储过程小问题
    mysql游标错误
    is not writable or has an invalid setter method错误的解决
    Struts2中关于"There is no Action mapped for namespace / and action name"的总结
  • 原文地址:https://www.cnblogs.com/sanduzxcvbnm/p/15431912.html
Copyright © 2011-2022 走看看