编程学习网 > PHP技术 > laravel > 记一次laravel把工程文件配置在nginx二级目录并怎么读取的问题
2021
07-10

记一次laravel把工程文件配置在nginx二级目录并怎么读取的问题

为了减少部署时ssl证书申请,降低配置成本想把所有laravel的前端工程配置在一个域名下,结果就卡在二级目录设置这块怎么都出不来结果,也没发现有哪篇文章能详细写一下这种情况下如何配置(可能对于大神来说这种问题是太简单了吧)。现在就把过程中遇到的问题写下来

本地目录配置:

/data/www/www.aaa.com |___ index.html |___ /bbb-laravel-web |___ resources |___ public | |___ index.php | |___ css | |___ ccc.page.css |____ ...(其他目录略) 

最终想达到的效果是:

浏览器输入www.aaa.com,访问的是/data/www/www.aaa.com/index.html
浏览器输入www.aaa.com/bbb/,访问的是laravel的主页
也就是/data/www/www.aaa.com/bbb-laravel-web/public/index.php 

一开始就按着访问后台接口的方式配置的

server {
    listen       80;
    listen 443;
    # ssl 部分省略;
    server_name www.aaa.cn;
    root    /data/www/www.aaa.cn; 
    
    access_log  /data/log/nginx/www.aaa.cn.access.log  main;
    error_log  /data/log/nginx/www.aaa.cn.error.log debug;
   
    location /{
        index index.php index.html;
     }
     
     location ^~ /bbb/ {
        try_files $uri /bbb-laravel-web/public/index.php;
        index  index.html index.htm;
        index  index.html index.php;
     }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
    
    location ~ \.php$ {
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
        set $script $uri;
        set $path_info "/";
        if ( $uri ~ "^(.+\.php)(.+)$" ) {
            set $script $1;
            set $path_info $2;
        }

        fastcgi_param APP_ENV debug;#这里是使得laravel读取.env.debug下的配置,laravel5.5及以上可以那么搞
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param SCRIPT_FILENAME $document_root/$script;
        fastcgi_param SCRIPT_NAME $script;
    }
} 

结果出现了

image.png

让我们看看都这段发生了什么:
1.首先去查看/data/log/nginx/www.aaa.cn.error.log
2018/08/20 15:25:45 [notice] 2685#2685: *6 "^(.+\.php)(.+)$" does not match "/bbb-laravel-web/public/index.php", client: 123.45.678.90, server: www.aaa.cn, request: "GET /bbb/ HTTP/1.1", host: "www.aaa.cn" 

为什么会出现不匹配的情况呢?
1.匹配流程
首先,nginx拿到www.aaa.com/bbb/匹配的是下面这段配置

location ^~ /bbb/ { try_files $uri /bbb-laravel-web/public/index.php; index  index.html index.htm; index  index.html index.php; } 

我们从开头的本地磁盘root目录(也就是/data/www/www.aaa.cn)下面是没有bbb文件夹,所以$uri是匹配不上的,这个时候就匹配到了“/bbb-laravel-web/public/index.php”。由于它是try_files的最后一项,所以就发生了一个重定向,重定向匹配到了下面这段

location ~ \.php$ {
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
        set $script $uri;
        set $path_info "/";
        if ( $uri ~ "^(.+\.php)(.+)$" ) {
            set $script $1;
            set $path_info $2;
        }

        fastcgi_param APP_ENV debug;#这里是使得laravel读取.env.debug下的配置,laravel5.5及以上可以那么搞
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param SCRIPT_FILENAME $document_root/$script;
        fastcgi_param SCRIPT_NAME $script;
    }
} 

这段发生了什么呢?我们先来列举下里面的变量

整个url:www.aaa.com/bbb-laravel-web/public/index.php
set $script $uri;  # $script=$uri=/bbb-laravel-web/public/index.php
set $path_info "/";   # $path_info="/"
 if ( $uri ~ "^(.+\.php)(.+)$" ) {
            set $script $1;  # $script=(.+\.php)
            set $path_info $2; # $path_info=(.+)
  }
fastcgi_param PATH_INFO $path_info;
fastcgi_param SCRIPT_FILENAME $document_root/$script;
fastcgi_param SCRIPT_NAME $script; 

这段是解析php的,重写了url,访问index.php下路由为变量path_info的页面:
如果匹配不上"^(.+.php)(.+)$",那么就访问路由为/的页面
如果匹配上了,就访问路由(.+)的页面。这个配置逻辑是没有问题的。
由于(.+)表示的是匹配任意字符1~n次,那么/bbb-laravel-web/public/index.php是匹配不上,这时应该访问路由为"/"的页面,那又为什么访问不了呢?

我一开始是怀疑是nginx配置的问题,但是这个404页面是laravel的,说明是可以访问到laravel的,只是laravel内部没有这个路由,但是实际上我是写了"/"路由的。那么laravel内部接收到的是什么路由呢?

本来想着去看一把Laravel内部路由执行的原理,找个地方打log。但是太耗时间了,这个时候用了点小聪明,既然不是“/”的话,那么还有可能的路由便是"/bbb/",于是在app/Provider/RouteServiceProvider.php里面给web路由加了个前缀

protected function mapWebRoutes() { Route::prefix('bbb') //这个就是加了的前缀
             ->middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web.php')); } 

然后再测试,居然能访问到“/”路由了,但是页面样式却没了。
问题终于解决了第一步,接下来我们来解决第二步。

首先是看看样式文件为什么没访问到。
这个时候可以在浏览器里右键查看源代码,然后点击样式文件的链接(链接如下)
,结果404了。

<link href="./css/ccc.page.css" rel="stylesheet" type="text/css"> 

接着就上服务器上看看nginx的error log,log的位置就在上面的配置中

error_log /data/log/nginx/www.aaa.cn.error.log debug; 

唔,就是上面这行,中间的是路径,最后的debug表示了log的级别

然后看到了这一行

2018/08/21 08:58:50 [error] 11646#11646: *360 open() "/data/www/www.aaa.cn/bbb/css/ccc.page.css" failed (2: No such file or directory), client: 123.45.678.90, server: www.aaa.cn, request: "GET /bbb/css/ccc.page.css HTTP/1.1", host: "www.aaa.cn", referrer: "https://www.aaa.cn/bbb/" 

我们看到开始的目录就知道,/data/www/www.aaa.cn是没有bbb文件夹的,那访问bbb/css/ccc.page.css一定是404。要解决这个问题,那就得重写请求了。

location ^~ /bbb {
     
     location ~* ^(.+)\.(gif|jpg|jpeg|png|css|js|ico)$ {

# rewrite语法:rewrite 正则表达式 目标文件  [flag]
# ^表示正则表达式起始,$表示正则表达式结束
# $1,$2,$3表示正则表达式中不同的匹配部分
# $2和$3中间的“\.”表示.号。因为.在正则表达式里是匹配
# 在这里 $1=([a-zA-Z0-9]{3,}),$2=(.+),$3=(gif|jpg|jpeg|png|css|js|ico)
            rewrite  '^/bbb/([a-zA-Z0-9]{3,})/(.+)\.(gif|jpg|jpeg|png|css|js|ico)$' /bbb-web-laravel/public/$1/$2.$3 last;
        }

        try_files $uri /bbb-laravel-web/public/index.php;
        #root   html;
        index  index.html index.htm;
        index  index.html index.php;
     } 

这下好了,不过我寻思着,这个配置能不能再优化下。比如把所有请求都写在public下面,最后的配置如下

location ^~ /meetdate { alias /data/www/www.aaa.cn/bbb-laravel-web/public; rewrite '^/meetdate(.*)' /bbb-laravel-web/public$1 last; } 

然后发现SCSS里面的配置url("/image/a.png")路径访问不到,查看源代码发现的路径变成了www.aaa.com/image/a.png,那当然访问不了。然后去看了laravel-sass的文档

image.png

这段话说了两个意思:
1.对于相对路径而言,laravel会在resource(请看最前面的本地路径)下寻找相关的图片文件拷贝到public/images下,然后url重写成了/images/a.png?xxxxxxx
2.对于绝对路径,laravel不会进行url重写
那么像我这种希望不重写,以便最终编译成"../images/a.png"的怎么办呢?
文档也给出了解决办法,就是编译sass的语句后面加上options,代码如下
mix.sass('resources/assets/app/app.scss', 'public/css')
   .options({     
      processCssUrls: false
   }); 

然后就OK了!

以上就是“记一次laravel把工程文件配置在nginx二级目录并怎么读取的问题”的详细内容,想要获取更多laravel教程欢迎关注编程学习网

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取