!?。。∞D(zhuǎn)載請(qǐng)注明作者和本文鏈接?。。?!
為了減少部署時(shí)ssl證書申請(qǐng),降低配置成本想把所有l(wèi)aravel的前端工程配置在一個(gè)域名下,結(jié)果就卡在二級(jí)目錄設(shè)置這塊怎么都出不來(lái)結(jié)果,也沒(méi)發(fā)現(xiàn)有哪篇文章能詳細(xì)寫一下這種情況下如何配置(可能對(duì)于大神來(lái)說(shuō)這種問(wèn)題是太簡(jiǎn)單了吧)。現(xiàn)在就把過(guò)程中遇到的問(wèn)題寫下來(lái)
本地目錄配置:
/data/www/www.aaa.com
|___ index.html
|___ /bbb-laravel-web
|___ resources
|___ public
| |___ index.php
| |___ css
| |___ ccc.page.css
|____ ...(其他目錄略)
最終想達(dá)到的效果是:
瀏覽器輸入www.aaa.com,訪問(wèn)的是/data/www/www.aaa.com/index.html
瀏覽器輸入www.aaa.com/bbb/,訪問(wèn)的是laravel的主頁(yè)
也就是/data/www/www.aaa.com/bbb-laravel-web/public/index.php
一開始就按著訪問(wèn)后臺(tái)接口的方式配置的
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;
}
}
結(jié)果出現(xiàn)了

讓我們看看都這段發(fā)生了什么:
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"
為什么會(huì)出現(xiàn)不匹配的情況呢?
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)下面是沒(méi)有bbb文件夾,所以$uri是匹配不上的,這個(gè)時(shí)候就匹配到了“/bbb-laravel-web/public/index.php”。由于它是try_files的最后一項(xiàng),所以就發(fā)生了一個(gè)重定向,重定向匹配到了下面這段
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;
}
}
這段發(fā)生了什么呢?我們先來(lái)列舉下里面的變量
整個(gè)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,訪問(wèn)index.php下路由為變量path_info的頁(yè)面:
如果匹配不上"^(.+.php)(.+)$",那么就訪問(wèn)路由為/的頁(yè)面
如果匹配上了,就訪問(wèn)路由(.+)的頁(yè)面。這個(gè)配置邏輯是沒(méi)有問(wèn)題的。
由于(.+)表示的是匹配任意字符1~n次,那么/bbb-laravel-web/public/index.php是匹配不上,這時(shí)應(yīng)該訪問(wèn)路由為"/"的頁(yè)面,那又為什么訪問(wèn)不了呢?
我一開始是懷疑是nginx配置的問(wèn)題,但是這個(gè)404頁(yè)面是laravel的,說(shuō)明是可以訪問(wèn)到laravel的,只是laravel內(nèi)部沒(méi)有這個(gè)路由,但是實(shí)際上我是寫了"/"路由的。那么laravel內(nèi)部接收到的是什么路由呢?
本來(lái)想著去看一把Laravel內(nèi)部路由執(zhí)行的原理,找個(gè)地方打log。但是太耗時(shí)間了,這個(gè)時(shí)候用了點(diǎn)小聰明,既然不是“/”的話,那么還有可能的路由便是"/bbb/",于是在app/Provider/RouteServiceProvider.php里面給web路由加了個(gè)前綴
protected function mapWebRoutes()
{
Route::prefix('bbb') //這個(gè)就是加了的前綴
->middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
然后再測(cè)試,居然能訪問(wèn)到“/”路由了,但是頁(yè)面樣式卻沒(méi)了。
問(wèn)題終于解決了第一步,接下來(lái)我們來(lái)解決第二步。
首先是看看樣式文件為什么沒(méi)訪問(wèn)到。
這個(gè)時(shí)候可以在瀏覽器里右鍵查看源代碼,然后點(diǎn)擊樣式文件的鏈接(鏈接如下)
,結(jié)果404了。
<link href="./css/ccc.page.css" rel="stylesheet" type="text/css">
接著就上服務(wù)器上看看nginx的error log,log的位置就在上面的配置中
error_log /data/log/nginx/www.aaa.cn.error.log debug;
唔,就是上面這行,中間的是路徑,最后的debug表示了log的級(jí)別
nginx的debug log設(shè)置請(qǐng)看:https://blog.csdn.net/defonds/article/details/11612247
然后看到了這一行
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是沒(méi)有bbb文件夾的,那訪問(wèn)bbb/css/ccc.page.css一定是404。要解決這個(gè)問(wèn)題,那就得重寫請(qǐng)求了。
location ^~ /bbb {
location ~* ^(.+)\.(gif|jpg|jpeg|png|css|js|ico)$ {
# rewrite語(yǔ)法:rewrite 正則表達(dá)式 目標(biāo)文件 [flag]
# ^表示正則表達(dá)式起始,$表示正則表達(dá)式結(jié)束
# $1,$2,$3表示正則表達(dá)式中不同的匹配部分
# $2和$3中間的“\.”表示.號(hào)。因?yàn)?在正則表達(dá)式里是匹配
# 在這里 $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;
}
這下好了,不過(guò)我尋思著,這個(gè)配置能不能再優(yōu)化下。比如把所有請(qǐng)求都寫在public下面,最后的配置如下
location ^~ /meetdate {
alias /data/www/www.aaa.cn/bbb-laravel-web/public;
rewrite '^/meetdate(.*)' /bbb-laravel-web/public$1 last;
}
然后發(fā)現(xiàn)SCSS里面的配置url("/image/a.png")路徑訪問(wèn)不到,查看源代碼發(fā)現(xiàn)的路徑變成了www.aaa.com/image/a.png,那當(dāng)然訪問(wèn)不了。然后去看了laravel-sass的文檔
文檔請(qǐng)見:Compiling Assets (Laravel Mix)

這段話說(shuō)了兩個(gè)意思:
1.對(duì)于相對(duì)路徑而言,laravel會(huì)在resource(請(qǐng)看最前面的本地路徑)下尋找相關(guān)的圖片文件拷貝到public/images下,然后url重寫成了/images/a.png?xxxxxxx
2.對(duì)于絕對(duì)路徑,laravel不會(huì)進(jìn)行url重寫
那么像我這種希望不重寫,以便最終編譯成"../images/a.png"的怎么辦呢?
文檔也給出了解決辦法,就是編譯sass的語(yǔ)句后面加上options,代碼如下
mix.sass('resources/assets/app/app.scss', 'public/css')
.options({
processCssUrls: false
});
然后就OK了!
撒花么么噠 ??ヽ(°▽°)ノ?
?。。。∞D(zhuǎn)載請(qǐng)注明作者和本文鏈接?。。?!