網(wǎng)站首頁 編程語言 正文
1. 概述
瀏覽器直接加載本地網(wǎng)頁的時候,如果網(wǎng)頁涉及到加載本地資源(如圖片),會出現(xiàn)跨域的問題。Qt的Qt WebEngine模塊基于Chromium項目,遇到這樣的情況也會出現(xiàn)跨域的問題。
2. 詳論
2.1. 傳參
理論上,我們可以像設置chrome瀏覽器跨域一樣(設置chrome瀏覽器跨域網(wǎng)上的資料非常多),給我們使用的Qt程序傳參:
char ARG_DISABLE_WEB_SECURITY[] = "--disable-web-security";
int newArgc = argc+1+1;
char** newArgv = new char*[newArgc];
for(int i=0; i<argc; i++) {
newArgv[i] = argv[i];
}
newArgv[argc] = ARG_DISABLE_WEB_SECURITY;
newArgv[argc+1] = nullptr;
QApplication myApplication(newArgc, newArgv);
Qt會將跨域參數(shù)傳遞到Qt WebEngine模塊的Chromium內(nèi)核中,從而實現(xiàn)跨域。
2.2. JS module
即使設置跨域,當使用JavaScript ES6 module的時候,仍然有可能會出現(xiàn)跨域的問題。
一個顯而易見的錯誤提示如下:
js: Failed to load module script: The server responded with a non-JavaScript MIME type of "". Strict MIME type checking is enforced for module scripts per HTML spec.
原因在于,在Chrome瀏覽器的某些版本中,ES6 module的功能不支持跨域(但是require.js卻可以)。現(xiàn)在最新版本的Chrome的跨域設置已經(jīng)可以支持ES6 module,但是Qt WebEngine模塊卻可能是比較低的Chromium版本,從而造成使用ES6 module遇到跨域問題。通常來說,越新的Qt版本,Chromium版本也會越高。
如果還是不想要服務器環(huán)境,那么一種解決方案就是自定義URL方案:
#include <QApplication>
#include <QWebEngineView>
#include <QWebEngineUrlScheme>
#include <QWebEngineProfile>
#include <QWebEngineUrlSchemeHandler>
#include <QWebEngineUrlRequestJob>
#include <QFile>
#include <QFile>
#include <QFileInfo>
#include <QMimeDatabase>
class QtSchemeHandler : public QWebEngineUrlSchemeHandler
{
public:
QtSchemeHandler(QObject *parent = nullptr):QWebEngineUrlSchemeHandler(parent)
{
}
void requestStarted(QWebEngineUrlRequestJob *request) override
{
QByteArray request_method = request->requestMethod();
if(request_method != "GET")
{
request->fail(QWebEngineUrlRequestJob::RequestDenied);
return;
}
QUrl request_url = request->requestUrl();
QString request_path = request_url.path();
//qDebug()<<request_url<<endl;
QString application_path = "D:/";
QFile *file = new QFile(application_path + request_path);
file->setParent(request);
connect(request, &QObject::destroyed, file, &QFile::deleteLater);
//qDebug()<<file->size()<<endl;
if(!file->exists()||file->size()==0)
{
printf("resource '{request_path}' not found or is empty");
request->fail(QWebEngineUrlRequestJob::UrlNotFound);
return;
}
QFileInfo file_info = QFileInfo(*file);
QMimeDatabase mime_database;
QMimeType mime_type = mime_database.mimeTypeForFile(file_info);
request->reply(QUrl(mime_type.name()).toEncoded(), file);
}
};
int main(int argc, char *argv[])
{
char ARG_DISABLE_WEB_SECURITY[] = "--disable-web-security";
int newArgc = argc+1+1;
char** newArgv = new char*[newArgc];
for(int i=0; i<argc; i++) {
newArgv[i] = argv[i];
}
newArgv[argc] = ARG_DISABLE_WEB_SECURITY;
newArgv[argc+1] = nullptr;
qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "7542"); //用于調(diào)試
QWebEngineUrlScheme scheme = QWebEngineUrlScheme("qt");
scheme.setFlags(QWebEngineUrlScheme::CorsEnabled);
QWebEngineUrlScheme::registerScheme(scheme);
//QApplication a(argc, argv);
QApplication a(newArgc, newArgv);
QWebEngineView view;
QtSchemeHandler *scheme_handler = new QtSchemeHandler();
view.page()->profile()->installUrlSchemeHandler("qt", scheme_handler);
view.page()->profile()->clearHttpCache(); //刪除緩存
//view.load(QUrl("D:/cesium/CesiumWork/3DTilesPhotogrammetry/3DTilesPhotogrammetry.html"));
view.load(QUrl("qt://local/cesium/CesiumWork/3DTilesPhotogrammetry/3DTilesPhotogrammetry.html"));
view.show();
return a.exec();
}
這個方案的本質(zhì)是將URL定義地址的資源給轉(zhuǎn)發(fā)了一遍。但是這種方案還是有局限性,經(jīng)過測試,在Qt5.15.2版本中可行,但在Qt5.12.5版本中不行。而且這樣所有的資源地址都得采用這一套URL方案。
3. 建議
其實個人還是不太建議再輕易嘗試使用本地網(wǎng)頁跨域了,畢竟這一點與Web的安全性背道而馳。最好還是讓網(wǎng)頁在服務器環(huán)境下吧,出問題的可能性會小一點。
4. 參考
- Qt QWebEngineView not allowed to load local resource
- PyQt5 How To Use JavaScript Modules
原文鏈接:https://www.cnblogs.com/charlee44/p/16204546.html
相關(guān)推薦
- 2022-12-24 c++重載運算符時返回值為類的對象或者返回對象的引用問題_C 語言
- 2022-04-19 教你如何從正在運行的容器創(chuàng)建?Docker?映像_docker
- 2021-12-09 C語言求兩個正整數(shù)的最大公約數(shù)示例代碼_C 語言
- 2024-02-01 啟動jar報錯(文件名、目錄名或卷標語法不正確。)
- 2023-05-09 C語言qsort函數(shù)用冒泡排序?qū)崿F(xiàn)過程詳解_C 語言
- 2022-11-08 python安裝包出現(xiàn)Retrying?(Retry(total=4,?connect=None,?
- 2022-06-12 Python利用subplots_adjust方法解決圖表與畫布的間距問題_python
- 2022-07-30 Oracle鎖表解決方法的詳細記錄_oracle
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支