小计 -- nginx 中的 $request_uri 和 laravel 中的REQUEST_URI之间的关系

最近,开发有一个大的Laravel项目,之前是使用路径来区分不同的API接口的,再在想改成用不同的域名。想要把之前的区分不同API的路径在url中去掉,因为已经使用不同的域名来区分了。这个在nginx上,要怎么配置呢?

具体需求说明:

之前访问不同的API接口是用url路径区分的:
接口1 http://xxx.com/api1/login
接口2 http://xxx.com/api2/login
接口3 http://xxx.com/api3/login
现在要改成用不同的域名区分:
接口1 http://api1.xxx.com/login
接口2 http://api2.xxx.com/login
接口3 http://api3.xxx.com/login
需求是在同一个站点的nginx上更改,如何实现把url中的路径信息给去掉,也就是访问http://api1.xxx.com/login 会自动访问 http://api1.xxx.com/api1/login

具体实现方法

我们知道,nginx中的laravel最主要的配置如下:

location / {
    try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
}
如何根据不同的域名,更新index.php?后面的$query_string呢?其实关键点在fastcgi.conf文件中,
root@xxx.com:/etc/nginx# vi fastcgi.conf 

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

laravel 会读取REQUEST_URI变量,来进行route。而REQUEST_RUI在fastcgi.conf配置中,就是nginx 的$request_uri,包含请求参数的原始URI,不包含主机名。合理的根据主机名,更改REQUEST_URI变量,就可以实现上面的需求。

根据上面的解释,上面的有关laravel的nginx配置更改为:

### 增加相应的api域名
server_name xxx.com api1.xxx.com api2.xxx.com api3.xxx.com
location / {
    try_files $uri $uri/ /index.php?$query_string;
}
### 把$request_uri 赋值给 $request_url
set $request_url $request_uri;
### 如果访问域名匹配 api1.xxx.com,把 $request_url 更新为 /api1/$request_uri
if ($host ~ api1.xxx.com) {
            set $request_url /api1$request_uri;
}
### 如果访问域名匹配 api2.xxx.com
if ($host ~ api2.xxx.com) {
            set $request_url /api2$request_uri;
}
### 如果访问域名匹配 api1.xxx.com
if ($host ~ api3.xxx.com) {
            set $request_url /api3$request_uri;
}

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    ### 把传给laravel 的REQUEST_URI 赋值为我们上面根据域名更新的的$request_url
    fastcgi_param      REQUEST_URI $request_url;
}

OK,相关设置完成!

坚持原创技术分享,您的支持将鼓励我继续创作!