最近在用uniapp做一个h5的项目(与后台不是同域),在开发的时候发现了一个跨域的问题,一般跨域的问题就是后台配置的问题了~

一般百度找到的方法,就是在入口文件index.php中添加以下代码:

header( "Access-Control-Allow-Origin : *" );
header( "Access-Control-Allow-Methods : POST,GET,OPTIONS" );

  有的时候,这样也行,一开始我也是这么弄的,正常请求了

随便弄了一个路由测试的,没有问题,但是当放在uniapp的request请求的时候就报错了,因为请求head中添加了自定义参数token(身份验证,这个就不多说了)

经过测试发现,只要不在head中添加自定义参数就没问题,于是接着找资料,发现还要添加一行:

header( "Access-Control-Allow-Headers : Token,Accept,Accept-Encoding,Accept-Language,Connection,Content-Length,Content-Type,Host,Origin,Referer,User-Agent,X-DevTools-Emulate-Network-Conditions-Client-Id" );

  意思就是将所有用到的head参数都写进去

—————分隔线————

本来到这就结束了,但实际并不是这样。。。。

在找资料的时候,发现一种使用tp5的钩子的方法,感觉不错,于是删除了上面添加的代码,改成下面这样:

1、在application\common 下新建behavior目录,在添加添加CronRun.php文件,内容如下:

<?php

namespace app\common\behavior;

use think\Exception;
use think\Response;

class CronRun
{
    public function run(&$dispatch){
        $host_name = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : "*";
        $headers = [
            "Access-Control-Allow-Origin" => $host_name,
            "Access-Control-Allow-Credentials" => 'true',
            "Access-Control-Allow-Methods" => 'POST,GET,OPTIONS',
            "Access-Control-Allow-Headers" => "Token,Accept,Accept-Encoding,Accept-Language,Connection,Content-Length,Content-Type,Host,Origin,Referer,User-Agent,X-DevTools-Emulate-Network-Conditions-Client-Id"
        ];
        if($dispatch instanceof Response) {
            $dispatch->header($headers);
        } else if($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
            $dispatch['type'] = 'response';
            $response = new Response('', 200, $headers);
            $dispatch['response'] = $response;
        }
    }
}

2、在application\tags.php 文件中修改两处:

<?php

// 应用行为扩展定义文件
return [
    // 应用初始化
    'app_init'     => [],
    // 应用开始
    'app_begin'    => [
        'app\\common\\behavior\\CronRun'
    ],
    // 模块初始化
    'module_init'  => [],
    // 操作开始执行
    'action_begin' => [],
    // 视图内容过滤
    'view_filter'  => [],
    // 日志写入
    'log_write'    => [],
    // 应用结束
    'app_end'      => [
        'app\\common\\behavior\\CronRun'
    ],
];

3、没有3了,这样就可以了,好爽,而且入口文件也没有动,感觉还是不错的。

然而,此时坑来了(当然,与上面的代码没有关系)

如果使用了tp5的路由,因为这个项目专门的接口项目,所以配置了config.php文件,启用了强制路由,然后为了保证系统的安全,在配置路由的时候没有使用Route::rule,而是根据接口使用的Route::get或Route::post

这时候我发现一个问题,h5请求接口的时候又跨域了,恩。。。。。闹心,经过排查发现,就是1、开了强制路由,2、定义路由的时候使用的Route::get,直接就写死了接口所允许的请求类型(Route::post定义的使用get请求就不行),而跨域会先发一个Option请求,系统正常响应后再发起正常请求,而我用了强制路由,所以一开始的Option请求就没有正常响应,所以。。。。

总结:

1、要么不使用强制路由

2、要么使用Route::rule或在第三个参数里面配置GET与OPTION

3、别忘了配合上面的代码一起使用~

版权声明:本文为lamplnmp原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/lamplnmp/p/13141689.html