最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Qt+QtWebApp開發(fā)筆記(六):http服務(wù)器html實現(xiàn)靜態(tài)相對路徑調(diào)用第三方j(luò)s文件

2023-06-16 13:14 作者:紅胖子_AAA紅模仿  | 我要投稿

前言

??前面做了一些交互,網(wǎng)頁是直接通過html對response進行返回的,這里QtWebApp與傳統(tǒng)的web服務(wù)器不同,傳統(tǒng)的web服務(wù)器可以調(diào)用同級目錄相對路徑或者絕對路徑下的js,而QtWebApp的httpserver是response返回當前頁面的問題,默認是無法調(diào)用的。
??為了解決調(diào)用一些依賴的如echarts等一些js的代碼模塊引入的問題,就需要靜態(tài)文件了。
本篇解說StaticFileController,在返回的html文本中調(diào)用外部js文件,類似的,其他文件都是一樣了,只是引入的后綴名不一樣。

Demo

??這里是調(diào)用靜態(tài)文件js的
??

??這里是重定向測試的
??

靜態(tài)文件(重要功能,如調(diào)用服務(wù)器的js文件等)

??如果QtWebapp無法傳遞存儲在服務(wù)器文件夾中的靜態(tài)文件,那么它將是不完整的。StaticFileController提供了這一功能。但在使用它之前,需要在ini文件中進行一些額外的配置設(shè)置:

[files] path=../docroot encoding=UTF-8 maxAge=90000 cacheTime=60000 cacheSize=1000000 maxCachedFileSize=65536

??

  • path:設(shè)置指定存儲靜態(tài)文件的基本文件夾。它是相對于配置文件的。還可以編寫絕對路徑名,如“/opt/server/docroot”或“C:/server/docroot”。

  • encoding:encoding參數(shù)僅用于*.txt和*.html文件,用于告訴瀏覽器這些文件的編碼方式。如果同時需要不同的編碼,則必須創(chuàng)建StaticFileController的多個實例——每個編碼一個。
    其他參數(shù)控制高速緩存。首先,應(yīng)該知道操作系統(tǒng)已經(jīng)緩存了文件。然而,發(fā)現(xiàn)Linux和Windows在處理小文件時都表現(xiàn)不佳。因此,建議使用應(yīng)用程序內(nèi)部緩存,但僅適用于小文件。

  • cacheTime:cacheTime控制文件在內(nèi)存中最多保存多少毫秒。值0表示,只要有足夠的空間,文件就會保留在內(nèi)存中。

  • cacheSize:cacheSize指定允許緩存占用的內(nèi)存量。一兆字節(jié)是一個很好的開始值。如果用戶請求的文件不在緩存中,則會刪除最舊的文件,為新文件騰出空間。

  • maxCachedFileSize:maxCachedFileSize控制緩存中單個文件的最大大小。web服務(wù)器應(yīng)用程序不會緩存較大的文件。但正如所寫的那樣,操作系統(tǒng)可以很好地緩存大文件。事實證明,64千字節(jié)是一個很好的開始值。

  • maxAge:maxAge參數(shù)的含義與cacheTime基本相同,但控制網(wǎng)絡(luò)瀏覽器的緩存,而不是服務(wù)器。

??需要一個指向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(); }

??現(xiàn)在可以在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"); }

??現(xiàn)在創(chuàng)建文件夾MyFirstWebApp/docroot/files,然后創(chuàng)建一個名為hello.HTML的HTML文件:

<html> ? ? <body> ? ? ? ? Hello World! ? ? </body> </html>

??啟動程序并打開http://localhost:8080/files/hello.html.瀏覽器將接收該文件的內(nèi)容。
??可以將其他文件(圖像、css、javascript…)添加到該文件夾中,如果愿意,還可以創(chuàng)建更多的子文件夾。
??如果出現(xiàn)“找不到文件”錯誤,調(diào)試消息將幫助找出服務(wù)器真正試圖加載的文件。

HTTP重定向

??有時想將瀏覽器重定向到另一個頁面。這通常用于需要用戶登錄的網(wǎng)站。如果用戶沒有登錄,他會被重定向到登錄頁面。當然,匿名用戶必須可以訪問登錄頁面本身。
??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服務(wù)器總是使用QByteArray而不是QString,原因很簡單:性能。整個HTTP協(xié)議都是基于8位編碼的,所以決定不浪費CPU時間,不必要地來回轉(zhuǎn)換。
但是當然可以使用Unicode。例子:

void UnicodeController::service(HttpRequest& request, HttpResponse& response) { ? ? QString chinese=QString::fromUtf8("美麗的花朵需要重癥監(jiān)護"); ? ? response.setHeader("Content-Type", "text/html; charset=UTF-8"); ? ? response.write(chinese.toUtf8(),true); }

??這是谷歌翻譯(不會說中文)提供的“美麗的花朵需要重癥監(jiān)護”的中文翻譯。
??從QString到UTF-8的轉(zhuǎn)換并不比到Latin1的轉(zhuǎn)換慢。因此,如果需要,請隨時使用Unicode。但千萬不要忘記使用QString::fromUtf8。如果只寫中文=“美麗的花朵需要重癥監(jiān)護“,只會得到亂碼。

Demo增量:實戰(zhàn)配置加載靜態(tài)文件

步驟一:準備代碼模板

??準備之前的demo v1.4.0模板:

maxCachedFileSize=65536

步驟二:新增靜態(tài)文件管理類用于全局使用

??


??

步驟三:新增靜態(tài)配置

??新增靜態(tài)配置,路徑調(diào)整問exe當前的子目錄www(符合后端基本習(xí)慣)

[files] path=../www encoding=UTF-8 maxAge=90000 cacheTime=60000 cacheSize=1000000

步驟四:初始化靜態(tài)文件

??


??

步驟五:在Index進行路徑文件分流

??必須分流,靜態(tài)文件指示的api和文件是先從處理過程然后再到靜態(tài)文件管理類的,所以有些是請求數(shù)據(jù)則需要在代碼中處理,這里之前是沒有這樣做,可查看“入坑一”。
??

??本Demo無法打開跳轉(zhuǎn)的staticFileUserJs,可查看“入坑二
??本Demo靜態(tài)文件無法調(diào)用js,請查看“入坑三”。

模塊化(有一些新增調(diào)整)

??

Demo源碼

etc/httpServer.ini(新增files)

[listener] ;ip=127.0.0.1 port=8080 readTimeout=60000 maxRequestSize=16000 maxMultiPartSize=10000000 minThreads=4 maxThreads=100 cleanupInterval=60000 [logging] fileName=../logs/httpserver.log ;fileName=/dev/stdout minLevel=CRITICAL bufferSize=100 maxSize=1000000 maxBackups=2 ;timestampFormat=dd.MM.yyyy hh:mm:ss.zzz timestampFormat=yyyy-MM-dd hh:mm:ss.zzz msgFormat={timestamp} {typeNr} {type} {thread} {msg} ;QT5 supports: msgFormat={timestamp} {typeNr} {type} {thread} {msg}\n ?in {file} line {line} function {function} [files] path=../www encoding=UTF-8 maxAge=90000 cacheTime=60000 cacheSize=1000000 maxCachedFileSize=65536

www/index.html(新增文件,靜態(tài)文件主頁)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> ? ? <meta http-equiv="X-UA-Compatible" content="IE=edge"> ? ? <meta name="viewport" content="width=device-width, initial-scale=1.0"> ? ? <title>長沙紅胖子Qt</title> </head> <body> <p>你好, 長沙紅胖子 QQ:21497936 www.hpzwl.com</p> <p><a href="helloworld">Hello world!</a></p> ? ? <p><a href="list">list</a></p> ? ? <p><a href="login">login</a></p> ? ? <p><a href="checkState">checkState</a></p> ? ? <p><a href="staticFileUseJs.html">staticFileUseJs</a></p> </body>

www/staticFileUseJs.html(新增文件,測試跳轉(zhuǎn)和js調(diào)用)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>長沙紅胖子Qt</title> </head> <body> <p><a>這里是檢測狀態(tài)Demo v1.5.0了</a></p> <p><a id="dt1">123.567</a></p> <p><a id="dt2">123.567</a></p> <p><button onclick="reset()">清空</button></p> <p><button onclick="getDt1()">獲取</button></p> <p><button onclick="doJs()">調(diào)用js</button></p> <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> <!-- 不成功引入js,引入js腳本要script分開,引入失敗則進入界面不會彈出alert --> <script src="jquery.min.js"></script> <script> function doJs() { alert($("li")[0]); } </script> </body>

StaticFileManager.h(全局使用靜態(tài)文件消息處理)

#ifndef STATICFILEMANAGER_H #define STATICFILEMANAGER_H #include <QObject> #include <QMutex> #include "httplistener.h" #include "staticfilecontroller.h" using namespace stefanfrings; class StaticFileManager : public QObject { ? ? Q_OBJECT private: ? ? 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 <QApplication> #include <QDir> #include <QDebug> #include <QDateTime> //#define LOG qDebug()<<__FILE__<<__LINE__ //#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__ //#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread() //#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd") #define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") StaticFileManager *StaticFileManager::_pInstance = 0; QMutex StaticFileManager::_mutex; StaticFileManager::StaticFileManager(QObject *parent) ? ? : QObject(parent), ? ? ? _pStaticFileController(0) { } StaticFileManager *StaticFileManager::getInstance() { ? ? if(!_pInstance) ? ? { ? ? ? ? QMutexLocker lock(&_mutex); ? ? ? ? if(!_pInstance) ? ? ? ? { ? ? ? ? ? ? _pInstance = new StaticFileManager(); ? ? ? ? } ? ? } ? ? return _pInstance; } StaticFileController *StaticFileManager::getStaticFileController() const { ? ? return _pStaticFileController; } void StaticFileManager::setStaticFileController(StaticFileController *pStaticFileController) { ? ? _pStaticFileController = pStaticFileController; }

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實時檢測狀態(tài) }; #endif // INDEXREQUESTHANDLER_H

IndexRequestHandler.cpp(調(diào)整了入口和放開靜態(tài)文件)

#include "IndexRequestHandler.h" #include "StaticFileManager.h" #include <QTextCodec> #include <QDebug> #include <QDateTime> //#define LOG qDebug()<<__FILE__<<__LINE__ //#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__ //#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread() //#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd") #define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") using namespace stefanfrings; IndexRequestHandler::IndexRequestHandler(QObject *parent) ? ? : HttpRequestHandler(parent) { ? ? // 返回文本(我們需要在瀏覽器上看,所以將Qt內(nèi)部編碼都轉(zhuǎn)成GBK輸出即可,不管他本身是哪個編碼) ? ? // WINDOWS: GBK ?GB2312 ? ? // LINUX ?: urf-8 // ? ?_pTextCodec = QTextCodec::codecForName("utf-8"); ? ? _pTextCodec = QTextCodec::codecForName("GBK"); } void IndexRequestHandler::service(HttpRequest &request, HttpResponse &response) { ? ? QString path = request.getPath(); ? ? LOG << path; ? ? if(path == "/" || path == "/index") ? ? { #if 0 ? ? ? ? // index使用代碼 ? ? ? ? QString str; ? ? ? ? str += "<!DOCTYPE html>" ? ? ? ? ? ? ? ?"<html lang=\"en\">" ? ? ? ? ? ? ? ?"<head>" ? ? ? ? ? ? ? ?"<meta charset=\"UTF-8\">" ? ? ? ? ? ? ? ?"<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">" ? ? ? ? ? ? ? ?"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" ? ? ? ? ? ? ? ?"<title>長沙紅胖子Qt</title>" ? ? ? ? ? ? ? ?"</head>" ? ? ? ? ? ? ? ?"<body>" ? ? ? ? ? ? ? ?" ? ?<p>你好, 長沙紅胖子 QQ:21497936 www.hpzwl.com</p>" ? ? ? ? ? ? ? ?" ? ?<p><a href=\"helloworld\">Hello world!</a></p>" ? ? ? ? ? ? ? ?" ? ?<p><a href=\"list\">list</a></p>" ? ? ? ? ? ? ? ?" ? ?<p><a href=\"login\">login</a></p>" ? ? ? ? ? ? ? ?" ? ?<p><a href=\"checkState\">checkState</a></p>" ? ? ? ? ? ? ? ?" ? ?<p><a href=\"staticFileUseJs.html\">staticFileUseJs</a></p>" ? ? ? ? ? ? ? ?"</body>"; ? ? ? ? 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切入靜態(tài)文件后,ajax也是請求路徑

問題

??Ajax未代碼捕捉,直接入靜態(tài)文件本身就無法變成api接口了。
??


??

原因

??加載的靜態(tài)文件,里面請求的任何東西只要調(diào)用靜態(tài)文件處理類來處理,則會都變成本地靜態(tài)文件(這里靜態(tài)文件主要是可以調(diào)用未傳遞過去到客戶端的文件,如.js文件等)

解決

??先得從一個頭部文件開始分流,一開始使用一個自定義的代碼消息處理,這個消息處理通過第一層路徑或者子路徑來判斷是否是靜態(tài)文件,后再扔給靜態(tài)文件,就可以繞開。
??而接口也是通過路徑進行判斷,然后用代碼進行返回,所以這種開發(fā)起來就混合了Qt和httpJs等靜態(tài)文件了。

入坑二:添加js靜態(tài)文件后直接跑飛404

問題

??

原因

??去掉js的代碼,未恢復(fù)正常
??去掉js的文件,未恢復(fù)正常
??檢查代碼發(fā)現(xiàn),是重定向問題
??


??請查詢發(fā)現(xiàn),favicon,即Favorites Icon的縮寫,顧名思義,便是其可以讓瀏覽器的收藏夾中除顯示相應(yīng)的標題外,還以圖標的方式區(qū)別不同的網(wǎng)站,就是網(wǎng)站的圖標。
??沒有圖標本來為空,而我們沒有分流該路徑,分流之后還是不行,再測試:
??

??

??經(jīng)過摸索,還發(fā)現(xiàn):
??


??再后來發(fā)現(xiàn),靜態(tài)文件這個是文件,需要后綴html,因為我們做qt的這塊使用代碼api習(xí)慣了,導(dǎo)致忽略了這點

解決

??

入坑三:加載了js靜態(tài)文件未彈窗

問題

??


??但是點擊沒有彈窗:
??

原因

??檢查,未放開.js,加載js沒有真的加載進去
??在靜態(tài)文件分流的地方,放開后綴.js的
??

??還是不行,測試發(fā)現(xiàn)必須引入js在單獨空的script里面。

解決

??且發(fā)現(xiàn)要分開:
??

??


Qt+QtWebApp開發(fā)筆記(六):http服務(wù)器html實現(xiàn)靜態(tài)相對路徑調(diào)用第三方j(luò)s文件的評論 (共 條)

分享到微博請遵守國家法律
永德县| 道孚县| 余姚市| 闽清县| 水城县| 溆浦县| 潼南县| 佛学| 卢龙县| 峨山| 嵊州市| 富平县| 内江市| 收藏| 永宁县| 卓资县| 新野县| 黎城县| 宝清县| 东方市| 安新县| 龙江县| 南安市| 诏安县| 丘北县| 石屏县| 庄河市| 登封市| 无棣县| 新乐市| 汨罗市| 临湘市| 山阴县| 临澧县| 望江县| 峨边| 灵石县| 灌云县| 改则县| 岚皋县| 浏阳市|