最新要闻
- 【环球聚看点】实力登场 汉马动力携四款动力产品亮相上海GPOWER 2023动力展
- 陕西加强养老服务设施规划建设新建城区 新建居住(小)区配建养老服务设施
- 员工没完成业绩被罚吃苦瓜 公司:激励团队 都是自愿的
- 最新消息:买2套到手23件:黑人好来超白茶牙膏套装5支39.9元
- 坦克300坐不住了 全新一代北京BJ40曝光 你会选谁?
- 环球观热点:RTX轻薄本怎么选?不妨看看这三款:13499元的华硕灵耀Pro14 2023无可挑剔
- 世界观察:维珍银河计划月底进行首次商务飞行:数百名旅客将上太空
- 车祸轻伤害要求赔偿多少
- 有没有类似天龙八部的游戏_类似天龙八部的网络游戏|当前报道
- 赤座茜出场_赤座茜
- 滴滴发布橙意保障计划:9成网约车司机月均抽成低于20%
- 私人山庄被网红闯入并造谣为鬼屋吓得房主不敢回了 网友:请严惩_热闻
- 梅西回应被迫“宅”酒店 酒店外的球迷太疯狂:感谢所有中国球迷 环球资讯
- 新资讯:问界M5智驾版交付 首位女车主还是兰博基尼、劳斯莱斯车主
- 两月没开电池报废不保修?极氪电池质保权益升级:砍掉不合理条约
- prscrn键在惠普键盘上哪个位置(prscrn)
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
Qt+QtWebApp开发笔记(六):http服务器html实现静态相对路径调用第三方js文件
前言
前面做了一些交互,网页是直接通过html对response进行返回的,这里QtWebApp与传统的web服务器不同,传统的web服务器可以调用同级目录相对路径或者绝对路径下的js,而QtWebApp的httpserver是response返回当前页面的问题,默认是无法调用的。 为了解决调用一些依赖的如echarts等一些js的代码模块引入的问题,就需要静态文件了。本篇解说StaticFileController,在返回的html文本中调用外部js文件,类似的,其他文件都是一样了,只是引入的后缀名不一样。
Demo
这里是调用静态文件js的
这里是重定向测试的
(资料图片仅供参考)
静态文件(重要功能,如调用服务器的js文件等)
如果QtWebapp无法传递存储在服务器文件夹中的静态文件,那么它将是不完整的。StaticFileController提供了这一功能。但在使用它之前,需要在ini文件中进行一些额外的配置设置:
[files]path=../docrootencoding=UTF-8maxAge=90000cacheTime=60000cacheSize=1000000maxCachedFileSize=65536
- path:设置指定存储静态文件的基本文件夹。它是相对于配置文件的。还可以编写绝对路径名,如“/opt/server/docroot”或“C:/server/docroot”。
- encoding:encoding参数仅用于*.txt和*.html文件,用于告诉浏览器这些文件的编码方式。如果同时需要不同的编码,则必须创建StaticFileController的多个实例——每个编码一个。其他参数控制高速缓存。首先,应该知道操作系统已经缓存了文件。然而,发现Linux和Windows在处理小文件时都表现不佳。因此,建议使用应用程序内部缓存,但仅适用于小文件。
- cacheTime:cacheTime控制文件在内存中最多保存多少毫秒。值0表示,只要有足够的空间,文件就会保留在内存中。
- cacheSize:cacheSize指定允许缓存占用的内存量。一兆字节是一个很好的开始值。如果用户请求的文件不在缓存中,则会删除最旧的文件,为新文件腾出空间。
- maxCachedFileSize:maxCachedFileSize控制缓存中单个文件的最大大小。web服务器应用程序不会缓存较大的文件。但正如所写的那样,操作系统可以很好地缓存大文件。事实证明,64千字节是一个很好的开始值。
- maxAge:maxAge参数的含义与cacheTime基本相同,但控制网络浏览器的缓存,而不是服务器。
需要一个指向StaticFileController实例的全局指针,以便整个程序都可以访问它。首先添加到global.h:
#ifndef GLOBAL_H#define GLOBAL_H#include "httpsessionstore.h"#include "staticfilefontroller.h"using namespace stefanfrings;extern HttpSessionStore* sessionStore;extern StaticFileController* staticFileController;#endif // GLOBAL_H
global.cpp:
#include "global.h"HttpSessionStore* sessionStore;StaticFileController* staticFileController;
在main.cpp中,配置StaticFileController的实例:
int main(int argc, char *argv[]){ QCoreApplication app(argc, argv); QString configFileName=searchConfigFile(); // Session store QSettings* sessionSettings=new QSettings(configFileName,QSettings::IniFormat,&app); sessionSettings->beginGroup("sessions"); sessionStore=new HttpSessionStore(sessionSettings,&app); // Static file controller QSettings* fileSettings=new QSettings(configFileName,QSettings::IniFormat,&app); fileSettings->beginGroup("files"); staticFileController=new StaticFileController(fileSettings,&app); // HTTP server QSettings* listenerSettings=new QSettings(configFileName,QSettings::IniFormat,&app); listenerSettings->beginGroup("listener"); new HttpListener(listenerSettings,new RequestMapper(&app),&app); return app.exec();}
现在可以在requestmapper.cpp中使用staticFileController:
#include "requestmapper.h"#include "httpsession.h"#include "global.h"void RequestMapper::service(HttpRequest& request, HttpResponse& response) { QByteArray path=request.getPath(); qDebug("RequestMapper: path=%s",path.data()); if (path=="/" || path=="/hello") { helloWorldController.service(request, response); } else if (path=="/list") { listDataController.service(request, response); } else if (path=="/login") { loginController.service(request, response); } else if (path=="/cookie") { cookieTestController.service(request, response); } else if (path.startsWith("/files")) { staticFileController->service(request,response); } else { response.setStatus(404,"Not found"); response.write("The URL is wrong, no such document."); } qDebug("RequestMapper: finished request");}
现在创建文件夹MyFirstWebApp/docroot/files,然后创建一个名为hello.HTML的HTML文件:
Hello World!
启动程序并打开http://localhost:8080/files/hello.html.浏览器将接收该文件的内容。 可以将其他文件(图像、css、javascript…)添加到该文件夹中,如果愿意,还可以创建更多的子文件夹。 如果出现“找不到文件”错误,调试消息将帮助找出服务器真正试图加载的文件。
HTTP重定向
有时想将浏览器重定向到另一个页面。这通常用于需要用户登录的网站。如果用户没有登录,他会被重定向到登录页面。当然,匿名用户必须可以访问登录页面本身。 requestmapper.cpp中的更改:
void RequestMapper::service(HttpRequest& request, HttpResponse& response) { QByteArray path=request.getPath(); qDebug("RequestMapper: path=%s",path.data()); QByteArray sessionId=sessionStore->getSessionId(request,response); if (sessionId.isEmpty() && path!="/login") { qDebug("RequestMapper: redirect to login page"); response.redirect("/login"); return; } else if (path=="/login") { ... } else if (path=="/whatever") { ... } qDebug("RequestMapper: finished request");}
国际化(ps:在文本中返回中文)
HTTP服务器总是使用QByteArray而不是QString,原因很简单:性能。整个HTTP协议都是基于8位编码的,所以决定不浪费CPU时间,不必要地来回转换。但是当然可以使用Unicode。例子:
void UnicodeController::service(HttpRequest& request, HttpResponse& response) { QString chinese=QString::fromUtf8("美丽的花朵需要重症监护"); response.setHeader("Content-Type", "text/html; charset=UTF-8"); response.write(chinese.toUtf8(),true);}
这是谷歌翻译(不会说中文)提供的“美丽的花朵需要重症监护”的中文翻译。 从QString到UTF-8的转换并不比到Latin1的转换慢。因此,如果需要,请随时使用Unicode。但千万不要忘记使用QString::fromUtf8。如果只写中文=“美丽的花朵需要重症监护“,只会得到乱码。
Demo增量:实战配置加载静态文件
步骤一:准备代码模板
准备之前的demo v1.4.0模板:
maxCachedFileSize=65536
步骤二:新增静态文件管理类用于全局使用
步骤三:新增静态配置
新增静态配置,路径调整问exe当前的子目录www(符合后端基本习惯)
[files]path=../wwwencoding=UTF-8maxAge=90000cacheTime=60000cacheSize=1000000
步骤四:初始化静态文件
步骤五:在Index进行路径文件分流
必须分流,静态文件指示的api和文件是先从处理过程然后再到静态文件管理类的,所以有些是请求数据则需要在代码中处理,这里之前是没有这样做,可查看“入坑一”。
本Demo无法打开跳转的staticFileUserJs,可查看“入坑二” 本Demo静态文件无法调用js,请查看“入坑三”。
模块化(有一些新增调整)
Demo源码
etc/httpServer.ini(新增files)
[listener];ip=127.0.0.1port=8080readTimeout=60000maxRequestSize=16000maxMultiPartSize=10000000minThreads=4maxThreads=100cleanupInterval=60000[logging]fileName=../logs/httpserver.log;fileName=/dev/stdoutminLevel=CRITICALbufferSize=100maxSize=1000000maxBackups=2;timestampFormat=dd.MM.yyyy hh:mm:ss.zzztimestampFormat=yyyy-MM-dd hh:mm:ss.zzzmsgFormat={timestamp} {typeNr} {type} {thread} {msg};QT5 supports: msgFormat={timestamp} {typeNr} {type} {thread} {msg}\n in {file} line {line} function {function}[files]path=../wwwencoding=UTF-8maxAge=90000cacheTime=60000cacheSize=1000000maxCachedFileSize=65536
www/index.html(新增文件,静态文件主页)
长沙红胖子Qt 你好, 长沙红胖子 QQ:21497936 www.hpzwl.com
www/staticFileUseJs.html(新增文件,测试跳转和js调用)
长沙红胖子Qt <script>function reset() {document.getElementById("dt1").innerHTML="---.---";document.getElementById("dt2").innerHTML="---.---";document.getElementById("dt3").innerHTML="---.---";}function getDt1() {var xhr = new XMLHttpRequest();xhr.open("GET","/checkState/data",true);xhr.send();xhr.onreadystatechange = function() {if(xhr.readyState === 4 && xhr.status === 200){document.getElementById("dt1").innerHTML = xhr.responseText;}}}</script><script src="jquery.min.js"></script><script>function doJs() {alert($("li")[0]);}</script>
StaticFileManager.h(全局使用静态文件消息处理)
#ifndef STATICFILEMANAGER_H#define STATICFILEMANAGER_H#include #include #include "httplistener.h"#include "staticfilecontroller.h"using namespace stefanfrings;class StaticFileManager : public QObject{ Q_OBJECTprivate: explicit StaticFileManager(QObject *parent = 0);public: static StaticFileManager *getInstance();public: StaticFileController *getStaticFileController() const;public: void setStaticFileController(StaticFileController *pStaticFileController);private: static StaticFileManager *_pInstance; static QMutex _mutex;private: StaticFileController *_pStaticFileController;};#endif // STATICFILEMANAGER_H
StaticFileManager.cpp
#include "StaticFileManager.h"#include "IndexRequestHandler.h"#include "HttpSessionStoreManager.h"#include #include #include #include //#define LOG qDebug()<<__FILE__<<__LINE__//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__//#define LOG qDebug()<<__FILE__<<__LINE__<
IndexRequestHandler.h
#ifndef INDEXREQUESTHANDLER_H#define INDEXREQUESTHANDLER_H#include "httprequesthandler.h"#include "HelloWorldRequestHandler.h"#include "ListRequestHandler.h"#include "LoginRequestHandler.h"#include "CheckStateRequestHandler.h"using namespace stefanfrings;class IndexRequestHandler : public HttpRequestHandler{public: IndexRequestHandler(QObject *parent = 0);public: void service(HttpRequest& request, HttpResponse& response);private: QTextCodec *_pTextCodec;private: HelloWorldRequestHandler _helloWorldRequestHandler; // hellowold消息处理 ListRequestHandler _listRequestHandler; // list消息处理 LoginRequestHandler _loginRequestHandler; // login消息处理,Demo v1.3.0 CheckStateRequestHandler _checkStateRequestHandler; // checkState实时检测状态};#endif // INDEXREQUESTHANDLER_H
IndexRequestHandler.cpp(调整了入口和放开静态文件)
#include "IndexRequestHandler.h"#include "StaticFileManager.h"#include #include #include //#define LOG qDebug()<<__FILE__<<__LINE__//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__//#define LOG qDebug()<<__FILE__<<__LINE__<" "" "" "" "" "" "长沙红胖子Qt " "" "" " 你好, 长沙红胖子 QQ:21497936 www.hpzwl.com
" " " " " " " " " " " ""; QByteArray byteArray = str.toUtf8(); response.write(byteArray);#else // index使用文件 LOG << path; StaticFileManager::getInstance()->getStaticFileController()->service(request, response);#endif }else if(path == "/helloworld") { _helloWorldRequestHandler.service(request, response); }else if(path == "/list") { _listRequestHandler.service(request, response); }else if(path == "/login" || path == "/login/out") { _loginRequestHandler.service(request, response); }else if(path == "/checkState" || path == "/checkState/data") { _checkStateRequestHandler.service(request, response); }else if( path.startsWith("/staticFileUseJs") || path == "/favicon.ico" || path.endsWith(".js")) { LOG << path; StaticFileManager::getInstance()->getStaticFileController()->service(request, response); }else {#if 0 LOG; response.setStatus(404,"Not found"); QString str; str = "The URL is wrong, no such document."; QByteArray byteArray = str.toUtf8(); response.write(byteArray);#else // 这里进行重定向 LOG << "重定向至/"; response.redirect("/");#endif }}
工程模板v1.5.0
入坑
入坑一:直接从listerner切入静态文件后,ajax也是请求路径
问题
Ajax未代码捕捉,直接入静态文件本身就无法变成api接口了。
原因
加载的静态文件,里面请求的任何东西只要调用静态文件处理类来处理,则会都变成本地静态文件(这里静态文件主要是可以调用未传递过去到客户端的文件,如.js文件等)
解决
先得从一个头部文件开始分流,一开始使用一个自定义的代码消息处理,这个消息处理通过第一层路径或者子路径来判断是否是静态文件,后再扔给静态文件,就可以绕开。 而接口也是通过路径进行判断,然后用代码进行返回,所以这种开发起来就混合了Qt和httpJs等静态文件了。
入坑二:添加js静态文件后直接跑飞404
问题
原因
去掉js的代码,未恢复正常 去掉js的文件,未恢复正常 检查代码发现,是重定向问题 请查询发现,favicon,即Favorites Icon的缩写,顾名思义,便是其可以让浏览器的收藏夹中除显示相应的标题外,还以图标的方式区别不同的网站,就是网站的图标。 没有图标本来为空,而我们没有分流该路径,分流之后还是不行,再测试:
经过摸索,还发现: 再后来发现,静态文件这个是文件,需要后缀html,因为我们做qt的这块使用代码api习惯了,导致忽略了这点
解决
入坑三:加载了js静态文件未弹窗
问题
但是点击没有弹窗:
原因
检查,未放开.js,加载js没有真的加载进去 在静态文件分流的地方,放开后缀.js的
还是不行,测试发现必须引入js在单独空的script里面。
解决
且发现要分开:
关键词:
Qt+QtWebApp开发笔记(六):http服务器html实现静态相对路径调用第三方js文件
【环球聚看点】实力登场 汉马动力携四款动力产品亮相上海GPOWER 2023动力展
陕西加强养老服务设施规划建设新建城区 新建居住(小)区配建养老服务设施
员工没完成业绩被罚吃苦瓜 公司:激励团队 都是自愿的
最新消息:买2套到手23件:黑人好来超白茶牙膏套装5支39.9元
坦克300坐不住了 全新一代北京BJ40曝光 你会选谁?
环球观热点:RTX轻薄本怎么选?不妨看看这三款:13499元的华硕灵耀Pro14 2023无可挑剔
世界观察:维珍银河计划月底进行首次商务飞行:数百名旅客将上太空
车祸轻伤害要求赔偿多少
每日快看:MySQL索引优化与查询优化
直播源码搭建平台技术知识:实时语音识别字幕呈现功能
有没有类似天龙八部的游戏_类似天龙八部的网络游戏|当前报道
赤座茜出场_赤座茜
滴滴发布橙意保障计划:9成网约车司机月均抽成低于20%
私人山庄被网红闯入并造谣为鬼屋吓得房主不敢回了 网友:请严惩_热闻
梅西回应被迫“宅”酒店 酒店外的球迷太疯狂:感谢所有中国球迷 环球资讯
新资讯:问界M5智驾版交付 首位女车主还是兰博基尼、劳斯莱斯车主
两月没开电池报废不保修?极氪电池质保权益升级:砍掉不合理条约
prscrn键在惠普键盘上哪个位置(prscrn)
雪佛兰萨博班,出演1750部电影的明星车,磁力悬挂控制系统-天天短讯
视频编码耗时长、编码帧发送失败…DVPP视频编码问题典型案例分析
形式化分析之BAN逻辑
什么是SEO
当前滚动:国家发展改革委:统调电厂存煤达到历史新高 今年迎峰度夏电力保供有坚实的基础
全球微头条丨国家发改委:今年迎峰度夏电力保供有坚实基础
每日简讯:盐碱地治理之“沽源方案”
真叫“翔龙”了 哈弗全新插混SUV亮相:形似老卫士、搭载Hi4电四驱|世界热闻
女生摆摊卖鸡脚边卖边吃 网友:吃饱了收摊回家
二代骁龙8平板来了:后置双摄、全金属机身设计-世界关注
Win11新文件管理器砍掉部分功能!微软:大众用户不常用 天天新视野
全球讯息:供应链大佬发话!博世中国总裁:汽车企业做手机是吃饱了没事干
蓝色协议职业推荐 最强职业选择攻略[多图]
新消息丨驻马店市西平县大宗秋粮作物播种基本结束
珊子直播(珊子)_世界报道
奔驰新GLA怎么样及奥迪RS5怎么样
天天观点:在南极尿尿会被冻住吗?
特斯拉开启大促:Model 3后轮驱动版补贴8千元 贷款利率优惠 全球聚焦
权威媒体:不带偏见去看 中国相机镜头已开始超越日本厂商_世界最新
Win11+鸿蒙 618组队出击 华为MateBook E系列二合一笔记本实现年轻人Office自由
别以赚钱为目标 及时行乐!张朝阳对年轻人喊话:在网上做个体职业者挺好
2023年6月郑州人才公寓申请时间具体什么时候开始?
世界球精选!真人版电影《芭比》确认引进 北美于7月21日上映
Spring Boot 实现定时任务动态管理,太爽了! 头条
当前讯息:【一步步开发AI运动小程序】十二、自定义一个运动分析器,实现计时计数01
微动态丨各地计划生育宣传标语大全_最新计划生育宣传标语口号大全
男生中考忘涂机读卡妈妈崩溃大哭 让人心疼:网友疑惑这怎么会忘? 新要闻
零刻GTR7迷你主机618大促:R7 7840HS只要2680元
斐济群岛发生7.2级地震 预计不会发生海啸 新资讯
Bungie程序员批暴雪太懒|焦点简讯
焦点速读:不寒而栗!英美团队称创造出全球首个合成人类胚胎模型 无需精子和卵子
联想小新Pro 2023酷睿版直降700元 32GB内存超大杯5599元
世界速读:有多少中国人 正假冒俄罗斯人直播带货?
小米14提前发:采用华星极窄边框直屏 颜值胜过iPhone 14 Pro 环球动态
今日看点:100个物联网项目(基于ESP32)1ESP32的基础
读数据压缩入门笔记05_字典转换|全球焦点
全球热消息:快速上手kettle(四)壶中可以倒出些啥?
【天天速看料】骁龙最强芯+2K直屏!宋紫薇预告iQOO 11S
世界看点:《小美人鱼》豆瓣评分人数38591人 口碑暴降至5.1分:国人都不爱看黑美人鱼?
北京理想汽车获得纯电/增程生产资质:规划有5款纯电新车
DC宇宙重启之作!超英大片《闪电侠》上映:蝙蝠侠、超女联手登场
主页不刷新!网易LOFTER深夜崩溃:大量用户以为账号被封
【全球新要闻】PC玩家:没SSD 以后游戏都不让玩了?
这涂装属实有点帅!迷彩版特斯拉Cybertruck亮相街头|环球快讯
顾客吐槽海底捞8块钱生菜仅2片 门店回应:精准按克称重 没问题-天天热头条
成龙晒合影悼念黄永玉 二人结缘于电影《十二生肖》
PC玩家:没SSD就没法玩游戏了
这次41位“乘客”上天!中国新纪录
网络传输中的重要参数-简单的网络画像 天天聚看点
文心一言 VS 讯飞星火 VS chatgpt (42)-- 算法导论5.4 6题_聚看点
新华书店真不差钱:顾客“只看不买” 营收仍有上千亿-焦点消息
每日焦点!杭州第19届亚运会奖牌“湖山”正式发布:印有断桥、三潭印月
Intel处理器品牌正式升级!有请全新的酷睿Ultra|环球消息
国产之光!比亚迪登2023年BrandZ最具价值榜前十:唯一中国汽车品牌
第三次博客:PTA题目集6-8总结-当前信息
索尼LYTIA公布新品:一口气推出5款5000万像素传感器_天天热点评
观热点:2岁女童误吞23颗磁力珠 医生:随时可能发生肠穿孔
亏电3.9升、纯电跑200km!比亚迪驱逐舰07申报:合资中型轿车发抖
《神鬼寓言》女性设计引热议:东西方怎么差这么多?
B社《星空》引力惊人:法国XSX销量暴涨1335%
Java并发(十)----线程之守护线程 今日讯
商务部:两个原因致全国实际使用外资以美元计下降_天天时快讯
打破国外垄断 国产GPU架构天狼星亮相:自研架构自主可控|即时焦点
全球短讯!贾跃亭透露创业心酸:被美国市场教育 战胜华尔街顶级破产黑帮
梅西今晚8点首发出场!直击北京工体蹲守现场:人满为患-环球时讯
理想L9 Pro来了!将取消激光雷达!预估售价42-43万元
天天日报丨体型太大!美国大码女子乘飞机被要求买2座位:吐槽称难受又费钱
微服务配置中心选型比较——Nacos、Apollo
记录--前端如何优雅导出多表头xlsx
昂利康:七氟烷原料药上市申请获批
新西兰经济陷入技术性衰退
天天热头条丨商品日报(6月15日):焦煤领涨商品市场 贵金属承压下行
新华指数|钢“财”说:库存降幅收窄,宏观情绪回暖|全球最资讯
新出行贺磊聊“李想疯狂输出的背后” 点名多位车企高管
北京工体梅西含量超标:今晚8点举行足球友谊赛-全球快看点
一加第四款《原神》联名机在路上了:这次主角是派蒙
双髻鲨头上的“锤子”有什么用? 世界热资讯
618先别买洗地机!分享几条你不知道的要点|即时焦点
万方查重多久出报告(万方查重)-全球速递
扩展中国剩余定理(EXCRT)
天天即时看!三类重要Linux文件的用途与区别