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

简介: 本文介绍了如何在ThinkPHP框架中配置跨域请求,使用了TP内置的跨域类`\think\middleware\AllowCrossDomain::class`。文章还讨论了小程序和web网页在跨域请求格式上的区别,并提供了解决方案,包括修改跨域中间件源码以支持`Origin`和`token`。此外,还介绍了微信小程序跨域请求的示例和web网页前端发送Axios跨域请求的请求拦截器配置。

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

  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. 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. 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)
});
相关文章
|
18天前
|
JavaScript API 开发工具
(H5-Web3D-ThreeJS)在网页三维CAD中绘制窗户模型
本文介绍了如何使用mxcad3d在网页中创建一个简单的三维窗户模型。通过官方教程搭建环境,编写绘制窗户模型的代码,并在点击按钮后展示模型效果。最终模型包括窗框和玻璃部分,具备丰富的三维建模功能和便捷的API支持。
|
27天前
|
Web App开发 前端开发 网络性能优化
Web网页端IM产品RainbowChat-Web的v7.2版已发布
RainbowChat-Web是一套Web网页端IM系统,是RainbowChat的姊妹系统(RainbowChat是一套基于开源IM聊天框架 MobileIMSDK (Github地址) 的产品级移动端IM系统)。
34 1
|
26天前
|
网络协议 API 网络安全
Web实时通信的学习之旅:轮询、WebSocket、SSE的区别以及优缺点
Web实时通信的学习之旅:轮询、WebSocket、SSE的区别以及优缺点
116 0
|
26天前
|
存储 前端开发 API
前端开发中,Web Storage的存储数据的方法localstorage和sessionStorage的使用及区别
前端开发中,Web Storage的存储数据的方法localstorage和sessionStorage的使用及区别
81 0
|
2月前
|
JSON 小程序 前端开发
towxml的使用,在微信小程序中快速将markdown格式渲染为wxml文本
本文介绍了在微信小程序中使用`towxml`库将Markdown格式文本渲染为WXML的方法。文章提供了`towxml`的概述、安装步骤、以及如何在小程序中配置和使用`towxml`进行Markdown解析的详细说明和代码示例。
|
1月前
|
Java 应用服务中间件 Apache
浅谈Tomcat和其他WEB容器的区别
Tomcat是一款轻量级的免费开源Web应用服务器,常用于中小型系统及并发访问量适中的场景,尤其适合开发和调试JSP程序。它不仅能处理HTML页面,还充当Servlet和JSP容器。相比之下,物理服务器是指具备处理器、硬盘等硬件设施的服务器,如云服务器,其设计目标是在处理能力、稳定性和安全性等方面提供高标准服务。简言之,Tomcat专注于运行Java应用,而物理服务器则提供基础计算资源。
|
29天前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
87 3
|
11天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
90 44
|
7天前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
18 1
|
9天前
|
XML 安全 PHP
PHP与SOAP Web服务开发:基础与进阶教程
本文介绍了PHP与SOAP Web服务的基础和进阶知识,涵盖SOAP的基本概念、PHP中的SoapServer和SoapClient类的使用方法,以及服务端和客户端的开发示例。此外,还探讨了安全性、性能优化等高级主题,帮助开发者掌握更高效的Web服务开发技巧。