以前在自有项目中使用thinkphp6接口跨域中间件一直都很正常,这次问题主要出在一个而开项目中。thinkphp6+jwt加之一些使用方法上并不规范,导致前端在请求接口时跨域一直失败。
首先分享一个跨域的中间件,用户可直接复制使用。以下内容放置于“/app/middleware”目录下,取名“CrosDomain.php”。内容如下:
- <?php
- declare (strict_types = 1);
- namespace app\middleware;
- use think\Response;
- /** * 全局跨域请求处理 * Class CrossDomain * @package app\middleware */
- class CrossDomain{
- public function handle($request, \Closure $next) {
- header('Access-Control-Allow-Origin: *');
- header('Access-Control-Max-Age: 1800');
- header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
- header('Access-Control-Allow-Headers: *');
- if (strtoupper($request->method()) == "OPTIONS") {
- return Response::create()->send();
- }
- return $next($request);
- }
- }
同时在“/app/middleware.php”文件中增加一句:
- <?php
- // 全局中间件定义文件
- return [
- // 全局请求缓存
- // \think\middleware\CheckRequestCache::class,
- // 多语言加载
- // \think\middleware\LoadLangPack::class,
- // Session初始化
- \think\middleware\SessionInit::class,
- \app\middleware\CrossDomain::class,
- ];
其实本身采用Thinkphp6自带的跨域中间件基本上都可以轻松实现跨域。但是这次遇到的问题竟然是option请求成功,正式get或post请求失败。
经过一番排查,最终问题锁定在"header"上,前端请求时header中增加了一个Sign参数,而后端跨域时“Access-Control-Allow-Headers:”列表中没有Sign参数。然后把上述第13行的代码设置为“*”前端跨域成功。
所以日常还是要细心一点,排查“Access-Control-Allow-Methods”和“Access-Control-Allow-Headers”与前端请求的header是否一致。