Laravel 強制執行 https

相信近年來大家都使用了SSL,在不同的控制版面或至cloudflare等等cdn都有強制轉跳https的功能

但我所指的是Laravel層面的強制使用https,即使.env 使用的網址不是http,系統都會強行轉到https

事件源頭

我建立了一個傻瓜式的 function 來做 sitemap,因為那個project是很小的網站,但經常會新增/刪除頁面,但我也剛好沒有研究其他sitemap套件,所以不如自行簡單寫一個

$content_header = '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
$topic = Topic::all();
$content = '';
foreach ($topic as $k => $v) {
    $content .= "<url>
    <loc>" . $v->link() . "</loc>
    <lastmod>" . $v->created_at->format('Y-m-d') . "</lastmod>
    </url>";
}
$content_footer = '</urlset>';

$output = $content_header . $content . $content_footer;
Storage::disk('public')->put('sitemap.xml', $output);

其實這樣已經ok了,但我發現為什麼生成出來的xml中所有網址都是http而不是https

上面的 $v->link() ,其實 link() 就是model中我生成的一個function

    public function link($params = []) {
        return route('topic.show', array_merge([$this->id, $this->title], $params));
    }

其實就是想獲得完整的網址,比如https://xxxx.com/123-hello/

問題來了,在bladel中使用 $v->link() 是會看到 https,但為什麼生成xml有問題?

搜尋原因

我一開始以為是.env問題,嘗試了多次都無法解決,然後嘗試在controller中直接dd($v->link()),我終於看到了!

我並不是一個技術深入研究的人,所以我沒有去深究,我初步只是了解到,可以是blade才能以完全網址來顯示url,在controller 即使以return route() 也沒有拿到https的顯示,相信是一層層析解的問題

解決方法

app/Providers/AppServiceProvider.php


use Illuminate\Support\Facades\URL;

public function boot() {

        URL::forceScheme('https');
}

引入Facades\URL 並執行URL::forceScheme('https')

改進版本

app/Providers/AppServiceProvider.php


use Illuminate\Support\Facades\URL;

public function boot() {

        if (env('APP_ENV') !== 'local') {
            URL::forceScheme('https');
        }

}

要加入判斷,如果不是local,才進行強制轉跳,因為很多時候在自己電腦開發測試時,是沒有用到https,會發生圖片/css文件等無法連線的問題

後記

我只是一位想用代碼去解決工作需求的人,不是一個很愛深究邏輯、framework core code的人,能解決問題,不直接影響效率就可以了,