Sailfish Webview
API DocumentationSailfish WebView
The Sailfish WebView provides a straightforward and flexible way for you to introduce access to Web pages and websites into your application.
The WebView component utilises the Sailfish OS browser engine, built using Mozilla gecko.
Using Sailfish WebView
Currently you have to explicitly link against qtmozembed-qt5 at build time. For this you need to modify both your spec file, and your pro file. In the spec file you should add line:
BuildRequires: pkgconfig(qt5embedwidget)
And in your pro file you should add line:
PKGCONFIG += qt5embedwidget
In order for PkgConfig to work, you need to have either
CONFIG += sailfishapp
or
CONFIG += link_pkgconfig
in your pro file.
C++ API
The C++ API consists of the following classes:
- the WebEngine class
- the WebEngineSettings class
QML API
The QML API is provided through the Sailfish.WebView import namespace
The QML types exposed in the QML API are as follows:
Example
The following examples demonstrates how the WebView component can be integrated into an existing application's QML code.
Example:
import QtQuick 2.0 import Sailfish.Silica 1.0 import Sailfish.WebView 1.0 ApplicationWindow { initialPage: Component { WebViewPage { WebView { anchors.fill: parent url: "http://www.sailfishos.org" } } } }
Popup Customization
The appearance and behaviour of some aspects of the WebView (for example, popups and other user-interaction dialogs) may be customized via the QML API. To do so, clients must implement the appropriate interface type, and register their implementations with the WebView via a PopupProvider which is then bound to the WebView's popupProvider
property.
WebView currently supports customization via the following interfaces:
- UserPromptInterface
- PromptPopupInterface
- ContextMenuInterface
- AlertPopupInterface
- ConfirmPopupInterface
- AuthPopupInterface
- PasswordManagerPopupInterface
- LocationPopupInterface
- WebrtcPermissionInterface
- BlockedTabPopupInterface
- SelectorPopupInterface
Debugging Web Applications
When debugging your application you can run it with the EMBED_CONSOLE=1
environment variable. In case you are interested in the requests that are made use the EMBED_CONSOLE=network
environment variable. When EMBED_CONSOLE
is enabled console messages are printed to the terminal.
Loading and using local resources
When Cross-Origin Resource Sharing is applied resources that are required and loaded from another origin should be made aware of the cross-origin boundary. The content security manager will intercept and verify requests that you are performing and in case there is a violation the request is denied.
With debugging enabled as described above, an example CORS failure could look like this:
[JavaScript Error: "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at file:///path-to-resource/myfile.js. (Reason: CORS request not http)."]
In particular, this is likely to block files served from local storage using the file URI scheme. In case you're developing a Web App with the need to serve local files, there are several approaches you can use to circumnavigate this.
Option 1. Don't serve the files locally at all
In many cases, while it can initially seem sensible to serve local files, you may find you can get the same or better capabilities by serving a remote version of your app instead.
Many Web Apps will use caching, Web Storage and similar technologies so that they can operate fully even when offline. The app will be served from the remote server on first run, but then run locally subsequently.
Running your app from a remote server also has the other obvious benefit that you can update your app remotely without having to upload a new version to the Jolla Store.
Nevertheless, if you're certain you want to serve your app entirely from local storage, there are still other options available to you.
Option 2. Use a local HTTP server
Running a local HTTP server with your content allows you to control the headers and manage the CORS headers appropriately.
In practice, running a local Web server doesn't need to be complex or resource intensive. There are various Qt-based web server implementations such as QtHttpServer and QtWebApp.
Mark Washeim has also created a very nice Sailfish WebView example app that uses a small Python script to expose a local web server for the WebView to pull its content from.
There are two key files in this project needed to provide the functionality.
The main QML file triggers execution of the Python server
Python { id: py Component.onCompleted: { addImportPath(Qt.resolvedUrl('.')); importModule('server', function () {}); setHandler('finished', function(newvalue) { console.debug(newvalue) }); startDownload(); } function startDownload() { call('server.downloader.serve', function() {}); console.debug("called") }
The code needed for the server lives in a single short Python file which can be tailored to serve files from a specified root directory.
Option 3. Disable CORS protection
Since resources served from the local file system using the file URI scheme are served without headers, there's unfortunately no way to add the required headers to the responses.
If neither of the two previous options are suitable for you and there is need to load resources with the file URI scheme, you can set the security.disable_cors_checks
preference to true
to bypass cross-origin resource sharing checks. This preference should be set before loading of any resources and only if you know what requests are sent.
It's important to note that this is disabling a security feature, which should always give you pause. If you use this option without being clear that all of your requests are local and trusted, then this is likely to introduce a security vulnerability to your app, so care is needed.
The following can be used to disable the CORS checks for all requests.
import Sailfish.WebEngine 1.0 ... WebView { ... Component.onCompleted: { WebEngineSettings.setPreference("security.disable_cors_checks", true, WebEngineSettings.BoolPref) } }
Alternatively you can also try disabling strict origin policy on the file URI scheme using the following. This comes with a similar warning.
import Sailfish.WebEngine 1.0 ... WebView { ... Component.onCompleted: { WebEngineSettings.setPreference("security.fileuri.strict_origin_policy", false, WebEngineSettings.BoolPref) } }
See also WebEngineSettings.