c++qtqt5qwebviewqwebengineview

Qt QWebEngineView not allowed to load local resource


Edit: This is not a duplicate. The linked question handles a CORS security question where the browser will not let you load scripts from different sources. My question is related to a basic resource loading scheme (file:/// vs qrc:/).

I am trying to load a local html document in a QWebEngineView by using the file:/// scheme. The html file also references the jquery library, which is stored locally. The code for loading the page is give below:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow w;

    // center window on desktop
    w.setGeometry(QStyle::alignedRect(
                      Qt::LeftToRight,
                      Qt::AlignCenter,
                      w.size(),
                      a.desktop()->availableGeometry()
                      ));

    // Add WebEngineView
    QWebEngineView* view = new QWebEngineView;
    QWebEngineSettings* settings = view->settings();
    settings->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, true);
    settings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls,true);

    view->setUrl(QUrl(QStringLiteral("file:///app/ui/main.html")));

    // Make it the one and only widget
    w.setCentralWidget(view);

    w.show();

    return a.exec();
}

And the minimalistic html document next:

<html>
<head>
<script src="libs/jquery-3.2.1.min.js"/>
</head>
<body>
<h2>Hello World</h2>
<script>
$(function() {
  alert('loaded');
});
</script>
</body>
</html>

The document loads fine but the JavaScript fails with the following error:

js: Not allowed to load local resource

How can I force the QWebEngineView to load and execute the script anyways?

Edit: I proceeded as suggested by @eyllanesc, and added all my files as a qrc resource. This works perfectly well now.

Here is the updated source code (note the reference to the qrc resource both in C++ and HTML code):

#include "mainwindow.h"
#include <QApplication>
#include <QWebEngineView>
#include <QStyle>
#include <QDesktopWidget>
#include <QWebEngineSettings>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow w;

    // center window on desktop
    w.setGeometry(QStyle::alignedRect(
                      Qt::LeftToRight,
                      Qt::AlignCenter,
                      w.size(),
                      a.desktop()->availableGeometry()
                      ));

    // Add WebEngineView
    QWebEngineView* view = new QWebEngineView;
    QWebEngineSettings* settings = view->settings();

    //settings->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, true);
    //settings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls,true);

    view->setUrl(QUrl("qrc:/ui/main.html"));

    // Make it the one and only widget
    w.setCentralWidget(view);

    w.show();

    return a.exec();
}

And corresponding html file:

<html>
<head>
  <script src="qrc:/ui/libs/jquery-3.2.1.min.js"></script>
</head>
<body>
<h2>Hello World</h2>
<script>
$(function() {
    alert( "Document ready!" );
});
</script>
</body>
</html>

Solution

  • If we place relative paths, these will always be routes relative to the executable, so it is necessary to make sure that the route exists.

    It seems strange that I did not recognize a simple .js since many I have used without problems, but I put the static (html, js, css, etc) in a resource .qrc since this will be part of the executable and therefore its Route will never change.