ThinkPHP6 - 综合笔记

跨域

jq 访问引发跨域,解决方式 3 步:

  1. 通过在路由中链式调用来设定一个或一组路由进行跨域,如
Route::get('apple', function(){return 'apple';})->allowCrossDomain();

或启用跨域中间件,该中间件框架已定义好,启用即可。启用方式是找到 app\middleware.php 文件,将框架预定义的中间件类加入进去

<?php

// 全局中间件定义文件
return [
    // 全局请求缓存
    // \think\middleware\CheckRequestCache::class,
    // 多语言加载
    // \think\middleware\LoadLangPack::class,
    // Session初始化
    // \think\middleware\SessionInit::class
    \think\middleware\AllowCrossDomain::class
];
  1. 如果有以下情况:
  • 用到了自定义的 header
  • 前端需要处理响应头

则可能需要修改预定义的中间件源码,或者自定义一个跨域中间件来用。举例:项目用到了 Authorization 头,且前端需要接收响应头中的该字段值并保存到本地,又不想修改源码,可以进行如下处理:

  • 新建 app\middleware\MyCORSMiddleware.php,使其继承框架 AllowCrossDomain
  • 覆盖 $header,根据需要添加或修改内容
<?php

namespace app\middleware;

use think\middleware\AllowCrossDomain;

class CustomCORSMiddleware extends AllowCrossDomain
{
    // 添加处理自定义请求头
    protected $header = [
        'Access-Control-Allow-Credentials' => 'true',
        'Access-Control-Max-Age'           => 1800,
        'Access-Control-Allow-Methods'     => 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
        'Access-Control-Allow-Headers'     => 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With',
		// 框架会拦截响应头,该字段作用允许输出响应头
        'Access-Control-Expose-Headers'    => 'Authorization'
    ];
}
  • app\middleware.php 中启用 MyCORSMiddleware
<?php

// 全局中间件定义文件
return [
    // 全局请求缓存
    // \think\middleware\CheckRequestCache::class,
    // 多语言加载
    // \think\middleware\LoadLangPack::class,
    // Session初始化
    // \think\middleware\SessionInit::class
	// 使用自定义中间件
    \app\middleware\CustomCORSMiddleware::class
];
  1. 调整对 OPTIONS 请求的处理
    到这里部分前端请求还是可能引发跨域,可能的原因在于 OPTIONS 依旧会进行完成流程的执行,因此在 public\index.php 中增加对 OPTIONS 请求的拦截,使其不进行后续任何处理,避免进入任何中间件、业务的执行,如
// [ 应用入口文件 ]
namespace think;

require __DIR__ . '/../vendor/autoload.php';

// 处理 options 请求
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With');
	// 执行 header 后立即结束
    exit;
}

// 执行HTTP应用并响应
$http = (new App())->http;

$response = $http->run();

$response->send();

$http->end($response);
posted @ 2022-02-09 16:42  试试手气  阅读(211)  评论(0编辑  收藏  举报