当前位置:首页 » 《资源分享》 » 正文

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

13 人参与  2024年03月24日 18:25  分类 : 《资源分享》  评论

点击全文阅读


TP 内置的跨域配置类 AllowCrossDomain

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

在这里插入图片描述

开启跨域

<?php  // 全局中间件定义文件  return [  // 全局请求缓存  // \think\middleware\CheckRequestCache::class,  // 多语言加载  // \think\middleware\LoadLangPack::class,  // Session初始化  \think\middleware\SessionInit::class,  // 全局注册 middleware token  //     app\middleware\CheckToken::class  // 跨域请求  \think\middleware\AllowCrossDomain::class  ];

跨域配置发生的问题

今天,在用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端跨域问题解决

源码如下:

<?php// +----------------------------------------------------------------------// | 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 <liu21st@gmail.com>// +----------------------------------------------------------------------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);    }}

只需要将上面的请求头配置修改如下即可(添加上 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',

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

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

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

微信小程序跨域请求示例
在微信小程序中,可以使用小程序提供的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)    }  })
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
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)});

点击全文阅读


本文链接:http://zhangshiyu.com/post/84943.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1