#qt #qml #fetch #chromium #qtwebengine
#qt #qml #выборка #chromium #qtwebengine
Вопрос:
Я пытаюсь создать пользовательскую схему для QtWebEngineView с помощью QWebEngineUrlSchemeHandler для обслуживания веб-страницы с локального диска. Страница использует Fetch API для запроса некоторых файлов json.
Вот реализация для моей пользовательской схемы
appschemehandler.cpp
AppSchemeHandler::AppSchemeHandler(QObject *parent):
QWebEngineUrlSchemeHandler(parent),
m_scheme(QWebEngineUrlScheme("app"))
{
m_scheme.setFlags(
QWebEngineUrlScheme::SecureScheme |
QWebEngineUrlScheme::LocalAccessAllowed |
QWebEngineUrlScheme::ViewSourceAllowed |
QWebEngineUrlScheme::ContentSecurityPolicyIgnored |
QWebEngineUrlScheme::CorsEnabled
);
QWebEngineUrlScheme::registerScheme(m_scheme);
}
void AppSchemeHandler::install()
{
QWebEngineProfile::defaultProfile()->installUrlSchemeHandler("app", this);
}
void AppSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
{
...
}
main.cpp
int main(int argc, char *argv[])
{
AppSchemeHandler appSchemeHandler(nullptr);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
appSchemeHandler.install();
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(amp;engine, amp;QQmlApplicationEngine::objectCreated,
amp;app, [url](QObject *obj, const QUrl amp;objUrl) {
if (!obj amp;amp; url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
main.qml
Window {
id: browser
visible: true
width: 800
height: 600
WebEngineView {
id: webengine
anchors.fill: parent
url: 'app://my-app'
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Lets Fetch!</title>
</head>
<body>
<h1>Lets Fetch!</h1>
<script>
fetch("/myFile.json").then(res => console.log(res.json()));
</script>
</body>
</html>
Все работает так, как должно, пока веб-страница не попытается fetch()
. Это то, что я получаю в консоли chromium.
Fetch API cannot load app://my-app/myFile.json. URL scheme "app" is not supported.
Я провел быстрый тест с помощью Electron, который предоставляет protocol.registerSchemesAsPrivileged()
, и проблем с использованием Fetch API нет. Итак, затем я проверил аргументы процесса electron и нашел --fetch-schemes=app
. Я думаю, что это не аргумент Chromium (Blink?), Поскольку изменений нет, даже если я передаю его в свое приложение Qt напрямую или через QTWEBENGINE_CHROMIUM_FLAGS
переменную среды.
Каков способ Qt добавления пользовательских схем выборки?
Комментарии:
1. поделитесь .qml…
2. @eyllanesc Я обновил свой вопрос. Это очень просто, поэтому я не думаю, что это слишком актуально при работе с пользовательскими схемами.
3. Верьте или нет, иногда, когда это кажется простым и ошибки не могут быть допущены, это является причиной проблемы (не обязательно в данном случае).
4. Не могу с этим поспорить. Был там миллион раз. : D
Ответ №1:
Это не правильный ответ на ваш вопрос (который, по-видимому, является известной ошибкой), а возможный обходной путь:
Похоже fetch()
, что он отлично работает с запросами, которые начинаются с URL-адреса http, а затем перенаправляются на пользовательскую схему с помощью a QWebEngineUrlRequestInterceptor
. Итак, для вашего примера выполните fetch("http://my-app/myFile.json")
в JavaScript, а затем перенаправьте это app://my-app/myFile.json
с помощью перехватчика. К сожалению, это означает изменение кода JavaScript, но это может быть лучше, чем ничего.
Это код Python, который я использовал, который должен быть простым для переноса на C :
class Interceptor(QtWebEngineCore.QWebEngineUrlRequestInterceptor):
def interceptRequest(self, info):
url = info.requestUrl()
if url.scheme() != 'http' or url.host() != 'my-app':
return
url.setScheme('app')
info.redirect(url)
Затем этот перехватчик устанавливается на QWebEngineProfile
с profile.setUrlRequestInterceptor(interceptor)
помощью .
Ответ №2:
Исправление было интегрировано в ветку разработки и будет доступно в Qt 6.6. Затем вы можете добавить QWebEngineUrlScheme::FetchApiAllowed
к флагам, и это должно сработать.
m_scheme.setFlags(
QWebEngineUrlScheme::SecureScheme |
QWebEngineUrlScheme::LocalAccessAllowed |
QWebEngineUrlScheme::ViewSourceAllowed |
QWebEngineUrlScheme::ContentSecurityPolicyIgnored |
QWebEngineUrlScheme::CorsEnabled |
QWebEngineUrlScheme::FetchApiAllowed
);