使用 Laravel 11.* 版本開發,不同網域的前後端時[例如:後端(api.demo.com),前端(demo.com)]
碰到 CORS 可以用以下的步驟排除
Laravel 設定
使用 php artisan 指令,執行
php artisan config:publish cors
上面這段指令是在專案的 config 資料夾內新增一個 cors.php 檔案,cors.php 的內部設定說明在下方
cors.php 設定方式如下
'paths' => ['api/* (開放給外面呼叫的路由)', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true, // 原本是false 記得改成 true
前端設定
前端使用 axios 來進行 ajax 請求,CDN 引入可以用以下的方式
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
或是參考 axios github 裡面有更詳細的介紹
前端檔案內可以如下設定
const api = axios.create({baseURL:"http://api.demo.com"});
api.defaults.withCredentials = true;
api.defaults.withXSRFToken = true;
這樣去進行 api.post 就可以通過囉
cors.php 內部說明
我們用一間超市來說明這些參數的用途
path
這像是超市的入口,決定哪些入口可以讓人進來。
本文上面範例說明:
‘paths’ => [”api/’, ‘sanctum/csrf-cookie’] 意思是只有 api/ 跟 sanctum/csrf-cookie 這個特定的路由會使用這些 CORS 設定,你有注意到 api/* 嗎,這代表著開放 api/ 以下的路由也都會使用cors的設定喔,例如 /api/members 也能夠吃到這個檔案的設定呢 。
allowed_methods
這像是超市裡允許客人做的事情,比如買東西、詢問價格等等。
本文上面範例說明:
‘allowed_methods’ => [‘*’] 表示允許所有的 HTTP 方法(GET, POST, PUT, DELETE 等等……)。如果你只想允許特定的方法,可以改成 [‘GET’, ‘POST’] 等等…..。
allowed_origins
這像是超市允許進入的客人類型,比如只允許會員進入。
本文上面範例說明:
‘allowed_origins’ => [‘*’] 表示允許所有的來源(即所有的網站)訪問。如果你只想允許特定的網站,這裡可以改成像 [‘http://demo.com’]。
allowed_origins_patterns
這像是允許某些特定模式的客人進入,比如只允許穿紅色衣服的客人。
本文上面範例說明:
這是用來匹配特定模式的來源。比如你可以設定 ‘allowed_origins_patterns’ => [‘https://*.demo.com’] 來允許所有 demo.com 的子域名。
allowed_headers
這像是允許客人帶進超市的物品,比如袋子、手機等等。
本文上面範例說明:
‘allowed_headers’ => [‘*’] 表示允許所有的 HTTP 標頭。
如果你只想允許特定的標頭,可以改成 [‘Content-Type’, ‘X-Requested-With’] 等等。
exposed_headers
這像是超市會告訴客人哪些資訊,比如特價商品信息。
本文上面範例說明:
這裡設定哪些 HTTP 標頭可以被客戶端訪問。如果有特定的標頭要暴露,可以在這裡設定。
‘exposed_headers’ => [‘expose_header’]
max_age
這像是超市允許客人在裡面逗留的時間。
本文上面範例說明:
‘max_age’ => 0 表示每次請求都需要進行 CORS 驗證。如果設置一個時間(秒為單位),在這個時間內的請求將不會重新驗證。
supports_credentials
這像是超市允許客人使用會員卡或其他憑證進入。
本文上面範例說明:
‘supports_credentials’ => true 表示允許請求攜帶憑證(如 cookies)。如果不需要憑證,可以設置為 false。
被 CORS 困住的朋友快來試試看吧!