qtqmlfetchchromiumqtwebengine

QtWebEngine Fetch API fails with custom scheme


Im trying to create custom schema for QtWebEngineView with QWebEngineUrlSchemeHandler to serve web page from local drive. Page is using Fetch API to request some json files.

Here is implementation for my custom scheme

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(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && 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>

Everything works as it should until web page is trying to fetch(). This is what I get to chromium console. Fetch API cannot load app://my-app/myFile.json. URL scheme "app" is not supported.

I made quick test with Electron that provides protocol.registerSchemesAsPrivileged() and there is no problems using Fetch API. So then I inspected electron process args and found --fetch-schemes=app. I think that is not Chromium (Blink?) arg since there is no change even if I pass it to my Qt application straight or through QTWEBENGINE_CHROMIUM_FLAGS environment variable.

What is the Qt way of adding custom fetch schemes?


Solution

  • A fix was integrated into the dev branch and will be available in Qt 6.6. You can then add QWebEngineUrlScheme::FetchApiAllowed to the flags and it should work.

    m_scheme.setFlags(
            QWebEngineUrlScheme::SecureScheme |
            QWebEngineUrlScheme::LocalAccessAllowed |
            QWebEngineUrlScheme::ViewSourceAllowed |
            QWebEngineUrlScheme::ContentSecurityPolicyIgnored |
            QWebEngineUrlScheme::CorsEnabled |
            QWebEngineUrlScheme::FetchApiAllowed
        );