C++ 网络编程项目fastDFS分布式文件系统(七)--qss样式表,项目文件的上传和下载。

news2024/9/23 13:26:29

目录

1 单例模式

2. 如何在单例类中存储数据?

3. QSS样式表

        3.1 选择器类型

3.2 QSS的使用步骤

 3.3 登录窗口设置

4. 客户端post方式上传数据

        4.1 常用的四种方式

5. 上传协议    


1 单例模式

#include<iostream>
#include<vector>
#include<mutex>
#include<thread>
#include<algorithm>
using namespace std;
 
//饿汉式
 
// class Singleton{
 
//     public:
//         static Singleton *GetInstance(){
//             return &m_instance;
//         }
 
//     private:
//         Singleton(){}
 
//         //c++ 98 防止拷贝
//         // Singleton(Singleton const &);
//         // Singleton& operator=(Singleton const &);
 
//         //c++ 11 防止拷贝
//         Singleton(Singleton const &)=delete;
//         Singleton& operator=(Singleton const &)=delete;
 
//         static Singleton m_instance;
 
// };
 
// Singleton Singleton::GetInstance();//在程序入口之前就完成初始化
 
//懒汉式
class Singleton{
 
    public:
        static Singleton *GetInstance(){
// 注意这里一定要使用Double-Check的方式加锁,才能保证效率和线程安全
            if(nullptr==m_pInstance){
                m_mtx.lock();
                if(nullptr==m_pInstance){
                    m_pInstance=new Singleton();
                }
                m_mtx.unlock();
 
            }
 
            return m_pInstance;
        }
 
        //实现一个内嵌的垃圾回收类
 
        class CGarbo{
 
            public:
                ~CGarbo(){
                    if(Singleton::m_pInstance){
 
                        delete Singleton::m_pInstance;
 
                    }
                }
 
        };
 
        static CGarbo Garbo;
 
    private:
    //构造函数私有
    Singleton(){}
 
    //防止拷贝
    Singleton(Singleton const &)=delete;
    Singleton &operator=( Singleton const&)=delete;
 
    static Singleton* m_pInstance;//单例对象指针
    static mutex m_mtx; //互斥锁
 
};
Singleton * Singleton::m_pInstance=nullptr;
Singleton::CGarbo Garbo;
mutex Singleton::m_mtx;
 
int main()
{
 
thread t1([]{cout<<(Singleton::GetInstance())<<endl;});
thread t2([]{cout<<(Singleton::GetInstance())<<endl;});
 
t1.join();
t2.join();
 
cout<<(Singleton::GetInstance())<<endl;
cout<<(Singleton::GetInstance())<<endl;
 
system("pause");
return 0;
}
 

        

2. 如何在单例类中存储数据?

        

// 实现了一个单例模式的类
// 存储用户名/密码/服务器的iP/端口
class Test
{
public:
static Test* getInstance()
{
return &m_test;
}
// 设置数据
void setUserName(QString name)
{
// 多线程-> 加锁
m_user = name;
// 解锁
}
// 获取数据
QString getUserName()
{
return m_user;
}
private:
Test();
Test(const Test& t);
// 静态变量使用之前必须初始化
// static Test* m_test;
static Test m_test;
// 定义变量 -> 属于唯一的单例对象
QString m_user;
QString m_passwd;
QString m_ip;
QString m_port;
QString m_token;
}
// Test* Test::m_test = new Test(); // 初始化
Test Test::m_test;
在客户端登录的时候 , 服务器回复给客户端的数据
        
// 成功
{
"code" : "000" ,
"token" : "xxx"
}
// 失败
{
"code" : "001" ,
"token" : "faild"
}
token -> 客户端成功连接了服务器 , 服务器针对于客户端的个人信息生成了一个唯一的身份标识
- 可以按照每个人的身份证号理解
- 服务器将这个 token 发送给客户端
- 客户端 token 的使用和保存 :
- 使用 : 登录成功之后 , 向服务器在发送任意请求都需要携带该 token
- 保存方式 : 放到单例对象中
- 服务器端的使用和保存 :
- 使用 : 接收客户端发送的 token , 和服务器端保存的 token 进行认证
- 认证成功 : 合法客户端 , 失败 : 客户端非法
- 保存 : 服务器需要保存所有客户端的 token
- 数据库中
- 配置文件 -> 效率低
- redis -> 效率最高
( 客户端信息 + 随机数 ) * des * md5 * base64

3. QSS样式表

        3.1 选择器类型

3.2 QSS的使用步骤

// QSS 是一个文件 , 样式表文件 (CSS 文件 )
// - Qt 样式表支持 css2.0, 1.0 所有的语法 , css3.0 部分样式在 qt 中不支持
// 如何使用
/*
1. 根据介绍的选择器对所有的控件样式设置 , 写入 qss 文件中
2. 在程序中读样式表文件 , 得到一个字符串 -> 样式字符串
3. 将读出的样式设置给 QT 的应用程序对象
4. qt 中有一个全局的应用程序指针 qApp
5. qApp->setStyleSheet(" 样式字符串 ");
6. QFile 读磁盘文件 , 磁盘文件的编码格式必须是 utf8
*/

 3.3 登录窗口设置

/* 登录窗口设置背景图片 */
/* 登录窗口所有控件设置字体 , 字体大小 */
/* 设置登录 / 注册 / 服务器设置窗口标题字体 , 字体大小 */
/* 设置 logo 显示的图片 */
/* 设置窗口标题字体 , 字体大小 , 加粗 */
/* 没有账号马上注册按钮 : 字体颜色和添加下划线 */
/* 登录 / 注册 /OK 按钮 : 字体颜色 , 宽度 , 高度 , 字体大小 , 显示图片 */
/* 标题栏按钮 : normal, hover, press 三种状态切换 */

/* 按钮的默认状态 */
QPushButton #loginBtn
{
color : white ;
width : 200 ;
height : 50 ;
font-size : 30px ;
border-image : url ( :/images/balckButton.png ); /* 默认显示的图片 */
}
/* 按钮的悬停状态 */
QPushButton #loginBtn : hover
{
border-image : url ( :/images/balckButton1.png ); /* 默认显示的图片 */
}
/* 按钮的按下状态 不是 css 中的标准状态 , qt 独有的 */
QPushButton #loginBtn : pressed
{
border-image : url ( :/images/balckButton2.png ); /* 默认显示的图片 */
}

4. 客户端post方式上传数据

        4.1 常用的四种方式

application/x-www-form-urlencoded
        
# 请求行
POST http: //www.example.com HTTP/1.1
# 请求头
Content-Type: application/x-www-form-urlencoded;charset=utf-8
# 空行
# 请求数据 ( 向服务器提交的数据 )
title=test&user=kevin&passwd=32222
application/json
        
POST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title": "test","sub":[1,2,3]}

 text/xml

POST http://www.example.com HTTP/1.1
Content-Type: text/xml
<?xml version="1.0" encoding="utf8"?>
<methodcall>
<methodname color="red">examples.getStateName</methodname>
<params>
<value><i4>41</i4></value>
</params>
</methodcall>
multipart/form-data
  tool.oschina.net
        
POST http://www.example.com HTTP/1.1
Content-Type: multipart/form-data
# 发送的数据
------WebKitFormBoundaryPpL3BfPQ4cHShsBz \r\n
Content-Disposition: form-data; name="file"; filename="qw.png"; md5="xxxxxxxxxx"
Content-Type: image/png\r\n;
\r\n
............. 文件内容 ................
............. 文件内容 ................
------WebKitFormBoundaryPpL3BfPQ4cHShsBz
Content-Disposition: form-data; name="file"; filename="qw.png"; md5="xxxxxxxxxx"
Content-Type: image/png\r\n;
\r\n
............. 文件内容 ................
............. 文件内容 ................
------WebKitFormBoundaryPpL3BfPQ4cHShsBz--

5. 上传协议    

文件上传的一般步骤 :
尝试秒传 -> 文件并没上传
给服务器发送的不是文件内容 , 是文件的哈希值
在服务器端收到哈希值 , 查询数据库
查到了 -> 秒传成功
没查到 -> 秒传失败 , 需要进行一个真正的上传操作
进行真正的上传
需要的时间长
上传有文件内容 , 文件的哈希值
文件内容 -> 分布式文件系统
哈希值 -> 数据库
1. 秒传 
 客户端
# url
http: //127.0.0.1:80/md5
# post 数据格式
{
user:xxxx,
token:xxxx,
md5:xxx,
fileName: xxx
}

服务器 

location / md5
{
# 转发数据
fastcgi_pass localhost:10002;
include fastcgi.conf;
}

int main()
{
while(FCGI_Accept() >= 0)
{
// 1. 得到post数据的长度
char* length = getenv("content-length");
int len = atoi(length);
// 2. 根据len将数据读到内存中, json对象字符串
// 3. 解析json对象, user,md5, token, fileName
// 4. token认证 , 查询redis/数据库
// -- 成功: 继续后续操作, 失败, 返回, 给客户端一个结果
// 5. 打开数据库, 并查询md5是否存在
// -- 存在 {"code":"006"}
// -- 不存在 {"code":"007"}
}
}

 2. 上传

        客户端

       

# url
http://127.0.0.1:80/upload
# post数据格式
------WebKitFormBoundary88asdgewtgewx\r\n
Content-Disposition: form-data; user="mike"; filename="xxx.jpg"; md5="xxxx";
size=10240
Content-Type: image/jpg
真正的文件内容
------WebKitFormBoundary88asdgewtgewx--
Qt 中如何组织上述 post 数据块
        
// 组织数据块 - > QHttpPart
QHttpPart::QHttpPart();
// 设置数据头
void QHttpPart::setHeader(QNetworkRequest::KnownHeaders header, const QVariant
&value);
- header:
- QNetworkRequest::ContentDispositionHeader
- QNetworkRequest::ContentTypeHeader
- value:
"form-data; 自定义的数据, 格式 xxx=xxx, 中间以;间隔"
// 适合传递少量的数据
void QHttpPart::setBody(const QByteArray &body);
- body: 传递的数据串
// 传递大文件
void QHttpPart::setBodyDevice(QIODevice *device);
- 使用参数device, 打开一个磁盘文件
// QHttpMulitPart
QHttpMultiPart::QHttpMultiPart(ContentType contentType, QObject *parent =
Q_NULLPTR);
- 参数contentType: QHttpMultiPart::FormDataType
// 调用该函数会自动添加分界线 -> 使用频率高的函数
void QHttpMultiPart::append(const QHttpPart &httpPart);
// 查看添加的分界线的值
QByteArray QHttpMultiPart::boundary() const;
// 自己设置分界线, 一般不需要自己设置
void QHttpMultiPart::setBoundary(const QByteArray &boundary);
// 使用post方式发送数据
QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request,
QHttpMultiPart *multiPart);
服务器
        
location /upload
{
# 转发数据
fastcgi_pass localhost:10003;
include fastcgi.conf;
}
// fastCGI程序
int main()
{
// 1. 获取数据长度 1024000
// 2. 循环读post数据内容
}

 服务器端fastCGI 部分 代码

        

 // 取出 Content-Disposition 中的键值对的值, 并得到文件内容, 并将内容写入文件
     int recv_save_file(char *user, char *filename, char *md5, long *p_size)
     {
         int ret = 0;
         char *file_buf = NULL;
         char *begin = NULL;
         char *p, *q, *k;
     
         char content_text[512] = {0}; //文件头部信息
         char boundary[512] = {0};     //分界线信息
     
         //==========> 开辟存放文件的 内存 <===========
         file_buf = (char *)malloc(4096);
         if (file_buf == NULL)
         {
             return -1;
         }
     
         //从标准输入(web服务器)读取内容
         int len = fread(file_buf, 1, 4096, stdin); 
         if(len == 0)
         {
             ret = -1;
             free(file_buf);
             return ret;
         }
     
         //===========> 开始处理前端发送过来的post数据格式 <============
         begin = file_buf;    //内存起点
         p = begin;
     
         /*
            ------WebKitFormBoundary88asdgewtgewx\r\n
            Content-Disposition: form-data; user="mike"; filename="xxx.jpg"; md5="xxxx"; size=10240\r\n
            Content-Type: application/octet-stream\r\n
            ------WebKitFormBoundary88asdgewtgewx--
         */
     
         //get boundary 得到分界线, ------WebKitFormBoundary88asdgewtgewx
         p = strstr(begin, "\r\n");
         if (p == NULL)
         {
             ret = -1;
             free(file_buf);
             return ret;
         }
     
         //拷贝分界线
         strncpy(boundary, begin, p-begin);
         boundary[p-begin] = '\0';   //字符串结束符
         p += 2; //\r\n
         //已经处理了p-begin的长度
         len -= (p-begin);
         //get content text head
         begin = p;
     
         //Content-Disposition: form-data; user="mike"; filename="xxx.jpg"; md5="xxxx"; size=10240\r\n
         p = strstr(begin, "\r\n");
         if(p == NULL)
         {
             ret = -1;
             free(file_buf);
             return ret;
         }
         strncpy(content_text, begin, p-begin);
         content_text[p-begin] = '\0';
     
         p += 2;//\r\n
         len -= (p-begin);
     
         //========================================获取文件上传者
         //Content-Disposition: form-data; user="mike"; filename="xxx.jpg"; md5="xxxx"; size=10240\r\n
         q = begin;
         q = strstr(begin, "user=");
         q += strlen("user=");
         q++;    //跳过第一个"
         k = strchr(q, '"');
         strncpy(user, q, k-q);  //拷贝用户名
         user[k-q] = '\0';
     
         //========================================获取文件名字
         //"; filename="xxx.jpg"; md5="xxxx"; size=10240\r\n
         begin = k;
         q = begin;
         q = strstr(begin, "filename=");
         q += strlen("filename=");
         q++;    //跳过第一个"
         k = strchr(q, '"');
         strncpy(filename, q, k-q);  //拷贝文件名
         filename[k-q] = '\0';
     
         //========================================获取文件MD5码
         //"; md5="xxxx"; size=10240\r\n
         begin = k;
         q = begin;
         q = strstr(begin, "md5=");
         q += strlen("md5=");
         q++;    //跳过第一个"
         k = strchr(q, '"');
         strncpy(md5, q, k-q);   //拷贝文件名
         md5[k-q] = '\0';
     
         //========================================获取文件大小
         //"; size=10240\r\n
         begin = k;
         q = begin;
         q = strstr(begin, "size=");
         q += strlen("size=");
         k = strstr(q, "\r\n");
         char tmp[256] = {0};
         strncpy(tmp, q, k-q);   //内容
         tmp[k-q] = '\0';
         *p_size = strtol(tmp, NULL, 10); //字符串转long
     
         begin = p;
         p = strstr(begin, "\r\n");
         p += 2; //\r\n
         len -= (p-begin);
     
         //下面才是文件的真正内容
         /*
            ------WebKitFormBoundary88asdgewtgewx\r\n
            Content-Disposition: form-data; user="mike"; filename="xxx.jpg"; md5="xxxx"; size=10240\r\n
            Content-Type: application/octet-stream\r\n
            真正的文件内容\r\n
            ------WebKitFormBoundary88asdgewtgewx--
         */
         // begin指向正文首地址
         begin = p;
         
         // 将文件内容抠出来
         // 文件内容写如本地磁盘文件
     
         free(file_buf);
         return ret;
     }
使用 fastCGI 管理器启动 fastCGI 程序
        
spawn-fcgi -a IP 地址 -p 端口 -f ./fastcgi 程序
- 提示启动失败
- ldd fastCGI 程序

4. Http 上传下载进度
        
// QNetworkReply - 信号
void QNetworkReply::downloadProgress ( qint64 bytesReceived , qint64 bytesTotal )
- bytesReceived : 已经接收的字节数
- bytesTotal : 要接收的总字节数
void QNetworkReply::uploadProgress ( qint64 bytesSent , qint64 bytesTotal )
- bytesSent : 已经发送的字节数
- bytesTotal : 要发送的总字节数

5. 上传大文件Nginx设置

        1. 413 错误

        

服务器提示:413 Request Entity Too Large 的解决方法
原因: 上传文件太大, 请求实体太长了
解决方案:
在配置文件nginx.conf中添加: client_max_body_size 10M
10M: 用户指定的大小
2. 设置的位置 :
http{ } 中设置: client_max_body_size 20m;
所有的 server 中的所有的 location 都起作用
server{ } 中设置: client_max_body_size 20m;
对当前 server 的所有的 location 生效
location{ } 中设置: client_max_body_size 20m;
只对当前 location 生效
3. 三者的区别是:
http{} 中控制着所有 nginx 收到的 http 请求。
报文大小限制设置在 server {}中,控制该 server 收到的请求报文大小
如果配置在 location 中,则报文大小限制,只对匹配了 location 路由规则的请求生效。

6. Qt中的哈希运算

        1. 哈希算法 - QCryptographicHash

        

// 构造哈希对象
1 QCryptographicHash ( Algorithm method );
// 添加数据
// c 格式添加数据
void QCryptographicHash::addData ( const char * data , int length );
// qt 中的常用方法
void QCryptographicHash::addData ( const QByteArray & data );
// 适合操作大文件
bool QCryptographicHash::addData ( QIODevice * device ); // QFile
- 使用 device 打开一文件 , addData 进行文件的读操作
// 计算结果
QByteArray QCryptographicHash::result () const ;
// 一般适合 , 哈希值都是使用 16 进制格式的数字串来表示
QByteArray QByteArray::toHex () const ;
[ static ] QByteArray QCryptographicHash::hash ( const QByteArray & data , Algorithm
method );
- 参数 data : 要运算的数据
- 参数 method : 使用的哈希算法
- 返回值 : 得到的哈希值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/931263.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python加入Excel--生产力大提高|微软的全方面办公

Python作为一种功能强大的编程语言&#xff0c;已经逐渐成为了数据分析、机器学习、Web开发等领域的主流语言之一。而将Python集成到Excel中&#xff0c;则可以为Excel用户提供更加强大的数据处理和分析能力&#xff0c;同时也可以为Python开发者提供更加便捷的数据处理和可视化…

法雷奥Valeo EDI解决方案

法雷奥集团&#xff08;Valeo&#xff09;是一家总部位于法国的专业致力于汽车零部件、系统、模块的设计、开发、生产及销售的工业集团。公司业务涉及原配套业务及售后业务&#xff0c;是世界领先的汽车零部件供应商&#xff0c;为世界上所有的主要汽车厂提供配套。作为一家高科…

UI位置与布局

UI位置与布局 引言 发现UGUI的RectTransform定位还是很复杂的&#xff0c;感觉有必要详细了解一下 RectTransform 继承自Transform。他的local position由其他几个变量控制。建议不要直接设置position 目的是为了实现UI自动布局。这套方法将绝对定位&#xff0c;相对定位&a…

若依移动端Ruoyi-App 项目的后端项目入门

后端项目运行 运行报错 Error creating bean with name sysConfigServiceImpl: Invocation of init method failed 数据库创建了。 代码连接数据库地方了也匹配上了。但是还是报错。 分析 &#xff1a; 想起来我电脑从来没有安装过redis 下载安装redis到windows 链接&…

C++简单的检测内存泄漏的代码(visual studio)

看了网上很多都需要安装这个库那个库&#xff0c;就很无语&#xff0c;一个初学者&#xff0c;给段代码不好么&#xff0c;然后我偶然发现了微软官方给的代码&#xff0c;链接如下 使用 CRT 库查找内存泄漏 | Microsoft Learn 代码如下 // debug_malloc.cpp // compile by u…

量子非凡暴风去广告接口

>>>https://videos.centos.chat/lzffbf.php/?url 免费提供综合去广告接口&#xff0c;各位请友好调用

033 - date 和 time

date类型&#xff1a; 该DATE类型用于具有日期部分但没有时间部分的值。MySQL检索并DATE以 格式显示 值 。支持的范围是 到。 YYYY-MM-DD1000-01-019999-12-31 -- 创建表&#xff0c;字段类型是date&#xff1a; create table test_date01 (a date); -- 正确格式插入数据 in…

学习ts(十一)本地存储与发布订阅模式

localStorage实现过期时间 目录 准备 安装 npm i rollup typescript rollup-plugin-typescript2// tsconfig.json"module": "ESNext","moduleResolution": "node", "strict": false, // rollup.config.js import …

Python语言实现React框架

迷途小书童的 Note 读完需要 6分钟 速读仅需 2 分钟 1 reactpy 介绍 reactpy 是一个用 Python 语言实现的 ReactJS 框架。它可以让我们使用 Python 的方式来编写 React 的组件&#xff0c;构建用户界面。 reactpy 的目标是想要将 React 的优秀特性带入 Python 领域&#xff0c;…

元类(metaclass)

目录 一、引言 二、什么是元类 三、为什么用元类 四、内置函数exec(储备) 五、class创建类 5.1 type实现 六、自定义元类控制类的创建 6.1 应用 七、__call__(储备) 八、__new__(储备) 九、自定义元类控制类的实例化 一十、自定义元类后类的继承顺序 十一、练习 p…

mysql my.ini、登录、用户相关操作、密码管理、权限管理、权限表,角色管理

my.ini 配置文件格式 登录mysql mysql -h hostname | IP -P port -u username -p database -e “select 语句”&#xff1b; 创建用户、修改用户、删除用户 create user ‘zen’ identified by ‘密码’ ## host 默认是 % create user ‘zen’‘localhost’ identified by ‘密…

构建安全可信、稳定可靠的RISC-V安全体系

安全之安全(security)博客目录导读 2023 RISC-V中国峰会 安全相关议题汇总 说明&#xff1a;本文参考RISC-V 2023中国峰会如下议题&#xff0c;版权归原作者所有。

YARN资源管理框架论述

一、简介 为了实现一个Hadoop集群的集群共享、可伸缩性和可靠性&#xff0c;并消除早期MapReduce框架中的JobTracker性能瓶颈&#xff0c;开源社区引入了统一的资源管理框架YARN。 YARN是将JobTracker的两个主要功能&#xff08;资源管理和作业调度/监控&#xff09;分离&…

HarmonyOS/OpenHarmony(Stage模型)卡片开发应用上下文Context使用场景一

1.获取应用文件路径 基类Context提供了获取应用文件路径的能力&#xff0c;ApplicationContext、AbilityStageContext、UIAbilityContext和ExtensionContext均继承该能力。应用文件路径属于应用沙箱路径。上述各类Context获取的应用文件路径有所不同。 通过ApplicationContext…

VR法治警示教育:情景式课堂增强教育效果

VR法治警示教育平台是一款基于虚拟现实技术的在线教育平台&#xff0c;旨在通过模拟真实场景和互动体验&#xff0c;向公众普及法律知识&#xff0c;提高公民的法律意识和素养。该平台采用先进的虚拟现实技术&#xff0c;将用户带入一个逼真的仿真环境&#xff0c;让用户身临其…

【广州华锐互动】VR沉浸式体验红军长征路:追寻红色记忆,传承红色精神

在历史的长河中&#xff0c;长征无疑是一段充满艰辛和英勇的伟大征程。为了让更多的人了解这段历史&#xff0c;我们利用虚拟现实&#xff08;VR&#xff09;技术&#xff0c;为您带来一场沉浸式的体验&#xff0c;重温红军万里长征的壮丽篇章。 一、踏上长征之路 戴上VR眼镜&a…

RocketMQ教程-(6-5)-运维部署-Promethus Exporter

介绍​ Rocketmq-exporter 是用于监控 RocketMQ broker 端和客户端所有相关指标的系统&#xff0c;通过 mqAdmin 从 broker 端获取指标值后封装成 87 个 cache。 警告 过去版本曾是 87 个 concurrentHashMap&#xff0c;由于 Map 不会删除过期指标&#xff0c;所以一旦有 la…

南方CASS软件安装包分享

目录 一、软件简介 二、软件下载 一、软件简介 南方CASS软件是一款基于AutoCAD平台开发的测量和计算设计软件&#xff0c;广泛应用于水利、电力、市政、建筑、交通等领域。 南方CASS软件集成了地形测量、断面测量、土地勘测定界、水文水利和公路设计等功能&#xff0c;为测…

JS 数组中对象 某属性相同对某属性的值进行相加去重(支持多条件多个值判断相加)

/* delSameObjValue 数组对象相同值相加去重arr 需要处理的数组resultNum 最终计算结果的键名keyName 用于计算判断的键名 keyValue 用于计算结果的键名 --> 对应的键值为number类型 */function delSameObjValue(arr, resultNum, keyName, keyValue) {const warp new Map(…

微信开发之一键创建微信群聊的技术实现

创建微信群 本接口为敏感接口&#xff0c;请查阅调用规范手册创建后&#xff0c;手机上不会显示该群&#xff0c;往该群主动发条消息手机即可显示。 请求URL&#xff1a; http://域名地址/createChatroom 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-T…