Qt QWebEngineView not allowed to load local resource

5.4k views Asked by At

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>
2

There are 2 answers

0
eyllanesc On BEST ANSWER

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.

0
Martin Dvorak On

If you need to load local resources, then you just need to pass --disable-web-security argument to QApplication, e.g.:

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);