4

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>
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
BigONotation
  • 4,406
  • 5
  • 43
  • 72
  • 1
    You could show the structure of your files, remember that the routes are relative to the executable, it is not relative to the source code. I recommend using a resource .qrc to save static files like js. – eyllanesc Aug 27 '17 at 21:35
  • @eyllanesc its not a relative path issue. The JavaScript file is found correctly but blocked from being executed. There must be some other setting – BigONotation Aug 27 '17 at 21:47
  • I have run code similar to yours many times and I have not had problems (the difference is that I use .qrc). You could share your code through github, drive or dropbox, since as you describe now I do not know where the .html or the .js – eyllanesc Aug 27 '17 at 21:50
  • @eyllanescOK will do so...thanks for the advice! :) – BigONotation Aug 27 '17 at 22:13
  • 1
    Possible duplicate of [QtWebEngine: "Not allowed to load local resource" for iframe, how to disable web security?](https://stackoverflow.com/questions/33730771/qtwebengine-not-allowed-to-load-local-resource-for-iframe-how-to-disable-web) – MrEricSir Aug 28 '17 at 01:43
  • @eyllanesc Many thanks! This worked. If you add your solution as an answer I will accept it :) – BigONotation Aug 28 '17 at 09:41
  • @MrEricSir Not a duplicate. Please refer to my edit at top of the page. Thanks – BigONotation Aug 28 '17 at 09:47

2 Answers2

2

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.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
1

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);
Martin Dvorak
  • 790
  • 8
  • 15