编程

Laravel 9 CORS 示例:如何在 Laravel 中启用 CORS

1129 2023-05-13 12:31:00

您不能在两个服务器或两个域名之间共享资源吗?好吧,如果你对此感到困惑,那么我们有一个解决方案。

本教程将介绍如何在 Laravel 中快速启用 CORS(Cross-Origin Resource Sharing,跨域资源共享)。你可以安装并配置 CORS,以消除 CORS header ‘access-control-allow-origin’ 缺失问题。

通常情况下,这个问题是在另一台服务器或源服务器发出请求时出现,因为两台服务器之间没有建立一致的安全问题。在响应中,我们通常会得到 “No 'Access-Control-Allow-Origin' header is present on the requested page“ 的警告。

跨源资源共享(CORS)是一种允许当前域(domain)的资源(比如 html/js/web service)被其他域(domain)的脚本请求访问的机制

Laravel 9 CORS 示例

如何在 REST API 后端启用 CORS? 首先安装全新的 Laravel 应用。

composer create-project laravel/laravel laravel-cors-tutorial --prefer-dist

进入项目目录:

cd laravel-cors-tutorial

如果你已经安装了 Laravel 应用可以跳过,直接运行下面命令测试 Laravel 中的 CORS。

php artisan serve

CORS 中间件

在安装新应用程序的同时,还生成了 config/cors.php 文件。Laravel 允许以下与 cors 相关的配置。

<?php
return [
    /*
    |--------------------------------------------------------------------------
    | Cross-Origin Resource Sharing (CORS) Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your settings for cross-origin resource sharing
    | or "CORS". This determines what cross-origin operations may execute
    | in web browsers. You are free to adjust these settings as needed.
    |
    | To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    |
    */
    'paths' => ['api/*'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['*'],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => false,
];

在 Laravel 中创建 API

要在 API 中启用 CORS,我们需要有一个路由,进入 routes/api.php 文件并添加下面路由。

<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::get('/demo-url',  function  (Request $request)  {
   return response()->json(['Laravel CORS Demo']);
});

使用 AJAX 发起 Http GET 请求

我们将使用 AJAX 发送 HTTP GET 请求。先创建一个 HTML 模板,命名为 demo.html。使用 jQuery CDN 链接,并定义 AJAX 函数,传入 Laravel API 以获取响应。

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
        integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
    <title>Laravel CORS Middleware Demo</title>
</head>
<body>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
    <script>
        $.ajax({
            type: "GET",
            dataType: "json",
            url: 'http://localhost:8000/demo-url',
            success: function (data) {
                console.log(data);
            }
        });
    </script>
    
</body>
</html>

Laravel CORS 错误

我们可以看到一个与 CORS 相关的错误(No ‘Access-Control-Allow-Origin’ header is present on the requested resource),这是因为我们有两个不同的域名试图相互交换数据。是的,我们甚至还没有启用 CORS。

Access to XMLHttpRequest at 'http://localhost:8000/demo-url' from origin 'null' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is 
present on the requested resource.

在  Laravel 中安装 CORS 包

我们已经知道是什么原因造成的,现在我们开始解决。使用 Composer 安装 fruitcake/laravel-cors 包:

composer require fruitcake/laravel-cors

注:Laravel ≥9.2.0 , 将 LARAVEL-CORS 包引入到框架中,因此请略过这步

注册 CORS 中间件

我们已经在 Laravel 应用中添加了典型的 CORS header 支持。现在,我们需要在应用中进行配置。

最后,在 app/Http/Kernel.php 文件的 $middleware 数组中引入 \Fruitcake\Cors\HandleCors 类,去启用所有路由的 CORS。

protected $middleware = [
  \Fruitcake\Cors\HandleCors::class,
  // Laravel >=9.2.0 请使用 \Illuminate\Http\Middleware\HandleCors::class, 
    // ...
    // ...
];

这样,我们就在 Laravel 中实现了 CORS, 让不同的域可以共享资源。