Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QWebEngineView "Access-Control-Allow-Headers" error while using wrld.js

I want to display a map via HTML/CSS/JS in a QWebEngineView using Qt5 C++.

It already works with leaflet (https://leafletjs.com/): enter image description here
As you can see the window shows a map with a marker at a given position.

However trying the same with wrld (https://github.com/wrld3d/wrld.js), a 3D map based on leaflet, I only get a black window: enter image description here
Additionally the following errors/warnings are displayed on the command line:

js: Refused to set unsafe header "Content-length"
js: Refused to set unsafe header "Connection"
js: Failed to load qrc://webgl-cdn1.eegeo.com/art_edits/continuous/incremental/us/sf/251/Ground/0/1/1/3/1/2/3/2/1/2/3/1/1/3/Ground.hcff?appinfo=Undefined%1Fb37aeaf9b6cd7eb5bc303d144af98ad0%1F1879%1Fd2cae54f44447344cfb3802d9365c03c3aa35e47%1FUndefined%1FUndefined%1FJavascript%1FUndefined%1FUndefined%1FJavascript: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
js: Uncaught abort() at Error
    at Sa (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:63:124)
    at Ra (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:63:22)
    at Object.q [as abort] (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:410:102)
    at _abort (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:257:368)
    at Rh (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:275:40424)
    at or (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:275:389787)
    at pgc (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:283:389489)
    at ogc (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:283:389037)
    at ldc (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:283:298507)
    at kdc (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:283:296713)
If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.

As far as I already figured out it has something to do with missing tags in the response header (Access-Control-Allow-Headers), but I can't get it working. I already tried to inject these headers via a QWebEngineUrlRequestInterceptor, but with no success.

Here is a minimal "working" example:

main.cpp:

#include <QApplication>
#include <QWebEngineView>

int main(int argc, char** argv) {
  qputenv("QT_STYLE_OVERRIDE", "Fusion");
  QApplication app(argc, argv);

  QWebEngineView* mapview = new QWebEngineView();
  mapview->load(QUrl("qrc:/map.html"));
  mapview->show();

  app.exec();

  return 0;
}

map.html: (you need an api key from https://www.wrld3d.com/ to use the wrld version)

<!doctype html>
<html lang="de">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
    integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
    crossorigin=""/>

    <!-- comment in for the leaflet version -->
    <!-- <script src="https://unpkg.com/[email protected]/dist/leaflet.js"
        integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
        crossorigin=""></script> -->

    <!-- wrld version -> not working -->
    <script src="https://cdn-webgl.wrld3d.com/wrldjs/dist/latest/wrld.js"></script>

</head>
<body>

<div id="mapid" style="width: 95vw; height: 95vh;"></div>
<script type="application/javascript">
    // comment in for the leaflet version
    // var map = L.map('mapid').setView([51.505, -0.09], 13);
    // L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    //   maxZoom: 18,
    //   attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
    //   '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
    //   'Imagery © <a href="http://www.openstreetmap.org/#map=6/51.">OpenStreetMap</a>',
    //   id: 'mapbox.streets'
    // }).addTo(map);

    var map = L.Wrld.map("mapid", "PUT_YOUR_API_KEY_HERE");
</script>
</body>
</html>

resources.qrc:

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <file>map.html</file>
</qresource>
</RCC>

CMakeLists.txt:

project (PROJ LANGUAGES CXX)

cmake_minimum_required (VERSION 3.9)

# set compiler flags for better warnings
add_compile_options(-Wall -Wextra -pedantic)


# set the required c++ standard to c++20
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)

# find Qt5
find_package(Qt5 REQUIRED Network WebEngine Widgets WebEngineWidgets)
qt5_add_resources(RCC_SOURCES resources.qrc)


# create executable with main file
add_executable(prog ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${RCC_SOURCES})
target_link_libraries(prog Qt5::Widgets Qt5::WebEngine Qt5::Network Qt5::WebEngineWidgets)

To run the example put all four files in one directory und use cmake/make to compile everything.

The desired output should look like: enter image description here

Is it possible to achieve that with Qt's QWebEngineView? Leaflet works fine. That is I see no real reason why it shouldn't work with wrld too.

like image 498
Arkantos493 Avatar asked May 07 '26 07:05

Arkantos493


1 Answers

This is not a Qt error but a wrld.js bug as noted in this discussion. From that conversion it is concluded that the library only supports http or https, and not another scheme.

So the solution is to launch the html through an HTTP server, there are several options but assuming that you only want to use Qt then we can take advantage of the following module: Qt HTTP server. To install it you must execute the following steps:

git clone --recursive https://codereview.qt-project.org/qt-labs/qthttpserver
cd qthttpserver
qmake
make
sudo make install

After that you must modify the main.cpp to:

#include <QApplication>
#include <QWebEngineView>
#include <QHttpServer>

int main(int argc, char** argv) {
    qputenv("QT_STYLE_OVERRIDE", "Fusion");
    QApplication app(argc, argv);

    QHttpServer httpServer;
    httpServer.route("/", []() {
        return QHttpServerResponse::fromFile(QStringLiteral(":/map.html"));
    });

    const auto port = httpServer.listen(QHostAddress::Any);
    if (port == -1) {
        qDebug() << QStringLiteral("Could not run on http://127.0.0.1:%1/").arg(port);
        return 0;
    }

    QWebEngineView view;
    view.load(QUrl(QStringLiteral("http://127.0.0.1:%1/").arg(port)));
    view.show();

    return app.exec();
}

And also the CMakeLists.txt:

project (PROJ LANGUAGES CXX)

cmake_minimum_required (VERSION 3.9)

# set compiler flags for better warnings
add_compile_options(-Wall -Wextra -pedantic)


# set the required c++ standard to c++20
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)

# find Qt5
find_package(Qt5 REQUIRED Network WebEngine Widgets WebEngineWidgets HttpServer)
qt5_add_resources(RCC_SOURCES resources.qrc)


# create executable with main file
add_executable(prog ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${RCC_SOURCES})
target_link_libraries(prog Qt5::Widgets Qt5::WebEngine Qt5::Network Qt5::WebEngineWidgets Qt5::HttpServer)

Resulting in:

enter image description here

like image 185
eyllanesc Avatar answered May 09 '26 08:05

eyllanesc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!