• ThinkPHP 配置跨域请求,使用TP的内置跨域类配置,小程序和web网页跨域请求的区别及格式说明


    TP 内置的跨域配置类 AllowCrossDomain

    TP 框架提供的内置类: \think\middleware\AllowCrossDomain::class

    在这里插入图片描述

    开启跨域

    
      // 全局中间件定义文件
      return [
      // 全局请求缓存
      // \think\middleware\CheckRequestCache::class,
      // 多语言加载
      // \think\middleware\LoadLangPack::class,
      // Session初始化
      \think\middleware\SessionInit::class,
      // 全局注册 middleware token
      //     app\middleware\CheckToken::class
      // 跨域请求
      \think\middleware\AllowCrossDomain::class
      ];
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    跨域配置发生的问题

    今天,在用ThinkPHP8做前后端分离配置跨域时,发现了一个小小的问题,就是我这块儿微信小程序发送token是完全正常的,但是使用web端网页发送请求它就会出现下面的错误
    Access to XMLHttpRequest at 'http://robin.com/Article?pagesize=10&page=1&status=-1&author=&title=' from origin 'http://localhost:5173' has been blocked by CORS policy: Request header field token is not allowed by Access-Control-Allow-Headers in preflight response.
    因为我使用的是TP框架自带的跨域配置类 \think\middleware\AllowCrossDomain::class,然后去查看了一下它的源码,发现其中确实少掉了Origin token的支持

    web端跨域问题解决

    源码如下:

    
    // +----------------------------------------------------------------------
    // | ThinkPHP [ WE CAN DO IT JUST THINK ]
    // +----------------------------------------------------------------------
    // | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
    // +----------------------------------------------------------------------
    // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
    // +----------------------------------------------------------------------
    // | Author: liu21st 
    // +----------------------------------------------------------------------
    declare(strict_types=1);
    
    namespace think\middleware;
    
    use Closure;
    use think\Config;
    use think\Request;
    use think\Response;
    
    /**
     * 跨域请求支持
     */
    class AllowCrossDomain
    {
        protected $cookieDomain;
    
        protected $header = [
            'Access-Control-Allow-Credentials' => 'true',
            'Access-Control-Max-Age'           => 1800,
            'Access-Control-Allow-Methods'     => 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
            // 此处就是 token 不支持设置的原因,因为配置项少了
            'Access-Control-Allow-Headers'     => 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With',
        ];
    
        public function __construct(Config $config)
        {
            $this->cookieDomain = $config->get('cookie.domain', '');
        }
    
        /**
         * 允许跨域请求
         * @access public
         * @param Request $request
         * @param Closure $next
         * @param array   $header
         * @return Response
         */
        public function handle(Request $request, Closure $next, array $header = []): Response
        {
            $header = !empty($header) ? array_merge($this->header, $header) : $this->header;
    
            if (!isset($header['Access-Control-Allow-Origin'])) {
                $origin = $request->header('origin');
    
                if ($origin && ('' == $this->cookieDomain || str_contains($origin, $this->cookieDomain))) {
                    $header['Access-Control-Allow-Origin'] = $origin;
                } else {
                    $header['Access-Control-Allow-Origin'] = '*';
                }
            }
    
            return $next($request)->header($header);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    只需要将上面的请求头配置修改如下即可(添加上 Origin, token ):

    'Access-Control-Allow-Headers'     => 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With,Origin, token',
    
    • 1

    在这里插入图片描述
    在这里插入图片描述

    微信小程序和web的跨域请求格式区别

    CORS(跨源资源共享)是一种更为现代和推荐的跨域解决方案。它通过服务器端设置响应头信息,允许来自不同源的客户端进行跨域请求。

    1. 微信小程序跨域请求示例
      在微信小程序中,可以使用小程序提供的JS-SDK中的wx.request方法发起CORS请求
    wx.request({  
      url: 'http://example.com/api', // 指定请求的URL地址  
      method: 'GET', // 指定请求方式  
      header: {  
        'Content-Type': 'application/json', // 设置请求头信息  
        'Access-Control-Allow-Origin': '*' // 设置允许跨域的源地址  
      },  
      success: function(res) {  
        // 请求成功后的回调函数  
        console.log(res.data)  
      },  
      fail: function(res) {  
        // 请求失败后的回调函数  
        console.log(res)  
      }  
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. web网页跨域请求后端配置
      在Web网页中,需要与服务端协商设置允许跨域的响应头信息,如下:
    Access-Control-Allow-Origin: *  
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS  
    Access-Control-Allow-Headers: Origin, Content-Type, X-Requested-With, token
    
    • 1
    • 2
    • 3
    1. web网页前端发送Axios跨域请求的请求拦截器配置
      一般前端发送请求,都是通过拦截器去对token进行一个封装。
    // request 拦截器
    // 可以自请求发送前对请求做一些处理
    // 比如统一加token,对请求参数统一加密
    request.interceptors.request.use(config => {
        config.headers['Content-Type'] = 'application/json;charset=utf-8';
        let token = localStorage.getItem("token") ? JSON.parse(localStorage.getItem("token")) : ""
        if(token!=""){
            config.headers['token'] = token;  // 设置请求头
        }
        return config
    }, error => {
        return Promise.reject(error)
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    列表变成向量 列表变向量 list vector
    慧尔视:以CRM为抓手,打造用数据说话的企业
    java计算机毕业设计基于安卓Android微信的团务智慧管理小程序uniAPP
    全面总结C++类模板使用的基础知识
    面试突击77:Spring 依赖注入有几种?各有什么优缺点?
    语法基础(数组)
    序列模型之循环神经网络(二)
    一起来学习flutter 的布局组件
    使用C语言EasyX 创建动态爱心背景
    Odoo | 如何隐藏tree视图中的列表表头?
  • 原文地址:https://blog.csdn.net/m0_63622279/article/details/133436707