Navigating to Content in Any Location
During the “Creating a Navigation App Project” section of this hour, we talked about the navigation model used in the last three project templates (Navigation, Split, and Grid). There we covered loading content (page controls) within our application. But sometimes we need to load content from the web.
Understanding the App Host
Running in Local Context
The protocol when using local context resources is ms-appx://. To access a local resource in our app, we would use ms-appx://ourpackage/someresource. We can use a shortcut by using three forward slashes and just set it to ms-appx:///someresouce. Using this protocol, we load content packaged in our app into the local context. This code has access to the Windows Runtime and all of the device’s hardware capabilities.
Inside the local context, any HTML that is injected into an app needs to be filtered by the window.toStaticHTML method, for security reasons. The local context allows the application to talk with the operating system and run with more privileges than a typical web browsing session. Because injecting HTML is a security risk, Windows runs any calls to innerHTML (and related operations) through a filtering process invoked by toStaticHTML. toStaticHTML simply walks through the data it is passed and strips out anything that resembles a script, while keeping the static HTML tags (like <b>) intact. If toStaticHTML is not called and script is present, an exception is thrown.
Running in Web Context
If we load content from the web, those pages are run in the web context. If we just link to content on the web, Windows opens the web browser and our app goes to the background. We cannot have a top-level navigation to web content. If we want to actually display the web content inside the app, we use an iframe. This way, the web resource that is loaded will function just it does in the browser. But it doesn’t have access to the user’s data, device hardware, or any of the Windows Runtime.
If we are trying to display unknown content, loading the iframe with the sandbox attribute set is best. By default, the iframe lets all scripts and form elements run and also gets information about the origin that could lead to accessing data such as cookie information. If we are loading our own resource on our web server or a well-known resource and we need the script or the form data to be processed as normal, we just pull it in with an iframe. However, if we are bringing up content that we don’t know about—perhaps something the user has been able to browse to—we want to make sure we put the iframe in sandbox mode. We have the option to tell it to execute scripts but not forms, or vice versa. We can let it access the origin information (which allows sharing local storage such as cookies) or keep it from doing so.
Using Third-Party Libraries
We don’t discuss any third-party libraries in this book because we don’t even enough pages to cover all the built-in functionality Microsoft provide, much less those provided by third-party libraries. However, Windows Store apps can definitely use third-party libraries.
Communicating Between Local Context and Web Context
Local context and web context can talk to each other by passing data through the postMessage function. This is a standards function that allows each iframe to share data at will. To use this function, we need to add an event listener for the window (not document) message event. Inside the event handler, we get the data being communicated in the event.data property (where event is the parameter of the event handler). For example:
The code to kick off that event looks similar to the following:
The idea is that this code is in an iframe and it is trying to send a message to the main default.html where it is hosted. It finds its parent window.parent and then calls its parent’s window.postMessage function. We cover this scenario in detail when we discuss how to work with passing messages between iframe elements securely during Hour 7.