Объединение приложений и веб-сайтов с помощью HTML x-ms-webview

OSzone.net » Microsoft » Разработка приложений » HTML5 » Объединение приложений и веб-сайтов с помощью HTML x-ms-webview
Автор: Кевин Хилл
Иcточник: MSDN
Опубликована: 25.09.2014

x-ms-webview — это мощный элемент управления, позволяющий встраивать веб-содержимое прямо в пользовательский интерфейс приложения. Этот элемент был доступен XAML-приложениям Магазина Windows начиная с версии Windows 8. В Windows 8.1 мы представили много всяческих обновлений, о которых можно прочитать в статье Сэма Спенсера «Что нового в WebView в Windows 8.1». Как сказано в статье Сэма, одно из крупнейших обновлений — то, что данный элемент управления теперь доступен для приложений, написанных на HTML и JavaScript!

Если вы разработчик приложений на HTML/JS, то x-ms-webview — прекрасный способ добавить в них веб-содержимое. В данной статье мы рассмотрим причины, почему вам захочется обновить свои приложения для использования x-ms-webview. Кроме того, я дам несколько рекомендаций касательно того, как воспользоваться всеми возможностями x-ms-webview.

Зачем мы создали HTML x-ms-webview?

Когда я разговариваю с HTML-разработчиками о новом элементе управления x-ms-webview, их первая реакция обычно такая: «Зачем мне это нужно?» Приложения на JavaScript имеют возможность размещать веб-контент в элементе iframe, так что это хороший вопрос. Но фреймы iframe имеют несколько ограничений, из-за которых встраивание веб-содержимого становится трудоемким, а в некоторых случаях — невозможным. Например:

x-ms-webview устраняет все эти проблемы и предоставляет новые функции, недоступные в iframe:

Итак, отвечая на исходный вопрос, зачем приложениям на HTML и JavaScript нужен webview... Все эти функции означают, что x-ms-webview — это просто лучший способ отображения веб-содержимого в ваших приложениях.

Как выглядит x-ms-webview?

Обратимся к основам: Webview — это HTML-элемент, являющийся частью DOM для приложений на JavaScript. Мы добавляем x-ms- к названию элемента x-ms-webview, обозначая тем самым, что это специальная функция HTML от поставщика (например, x-vendor-feature). Использование этого элемента должно показаться знакомым, потому что его синтаксис схож с iframe.

HTML-элемент

<x-ms-webview id="webview" src="http://www.bing.com"></x-ms-webview>

JavaScript

var webview = document.createElement("x-ms-webview");

Добавление базового элемента управления x-ms-webview на страницу default.html в приложении Windows Store, написанном на JavaScript, выглядит так:

HTML

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8" />

<title>WebView</title>

<!-- WinJS references -->

<link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />

<script src="//Microsoft.WinJS.2.0/js/base.js"></script>
 1:
 2:
 3: <script src="//Microsoft.WinJS.2.0/js/ui.js">
 1: </script>
 2:
 3: <!— app references -->
 4:
 5: <link href="/css/default.css" rel="stylesheet" />
 6:
 7: <script src="/js/default.js">
</script>

</head>

<body>

<x-ms-webview id="webview" src="http://www.bing.com" width="500px" height="500px"></x-ms-webview>

</body>

</html>

Если просто добавить элемент управления x-ms-webview, его размер по умолчанию составит 100 х 100 пикселей. Вы можете задать ширину и высоту так же, как в случае с iframe, либо использовать CSS-стили для iframe.

Навигация с x-ms-webview

Теперь, когда вы познакомились с элементом управления x-ms-webview и тем, как он загружает содержимое, вы понимаете процесс навигации и можете контролировать происходящее. Одна из часто встречающихся у разработчиков для Windows 8 проблем при внедрении веб-содержимого в приложения — определение момента полной загрузки DOM, чтобы начать управление DOM-объектами или выполнение JavaScript. x-ms-webview поддерживает события путей навигации, а также историю навигации, предоставляя контроль над веб-содержимым, загружаемым в приложение.

*
Увеличить

Свойства и методы истории навигации

API для работы с навигацией x-ms-webview

navigate() — при вызове этого API вы можете также подписаться на следующие события, которые инициируются во время запроса Navigation:

Название события DOMОписание
MSWebViewNavigationStartingОбозначает начало навигации WebView
MSWebViewContentLoadingHTML-содержимое загружено и сейчас вставляется в элемент управления
MSWebViewDOMContentLoadedОбозначает, что главные элементы DOM закончили загрузку
MSWebViewNavigationCompletedОбозначает, что навигация завершена, и все медиаэлементы отображены
MSWebViewUnviewableContentIdentifiedWebView обнаружил, что содержимое не является HTML

Если на загружаемом сайте есть iframe, то вы можете использовать еще несколько событий, чтобы обнаружить загрузку дополнительного содержимого через iframe:

Название события DOMОписание
MSWebViewFrameNavigationStartingОбозначает, что iframe внутри WebView начинает навигацию
MSWebViewFrameContentLoadingHTML-содержимое загружено и вставляется в элемент управления iframe
MSWebViewFrameDOMContentLoadedОбозначает, что главные элементы DOM закончили загрузку в iframe
MSWebViewFrameNavigationCompletedОбозначает, что навигация завершена, и все медиаэлементы отображены в iframe

История навигации x-ms-webview. 

Обнаружить, совершил ли пользователь навигацию внутри x-ms-webview, очень просто с помощью данных свойств и методов.

Свойства:

Методы:

История навигации JavaScript

HTML

…

<body>

<p>Content goes here</p>

<x-ms-webview id="webview" src="http://t.msn.com"></x-ms-webview>

<div id="webviewNavigationButtons"><button id="goBack" onclick="goBack()" disabled>Back</button><button id="goForward" onclick="goForward()" disabled>Forward</button></div>

</body>

…

CSS

#webview{

width:500px;

height:500px;

}

button{

margin-right:15px;

}

JavaScript

webview.addEventListener("MSWebViewContentLoading", webViewContentLoading);

function webViewContentLoading(e) {

document.getElementById("goBack").disabled = !webview.canGoBack;

document.getElementById("goForward").disabled = !webview.canGoForward;

}

function goBack() {

webview.goBack();

}

function goForward() {

webview.goForward();

}

Источники контента

Теперь, когда мы знаем, что WebView — это простой HTML-элемент, давайте рассмотрим типы содержимого, которые можно загружать в x-ms-webview, и различные методы, доступные для каждого из них.

*
Увеличить

Изображение, демонстрирующее методы навигации в Интернете и по локальному содержимому

Интернет-содержимое

Чаще всего элемент x-ms-webview используется для интеграции онлайн-содержимого из Интернета. Например, мы разработали для конференции Build 2013 демонстрационное приложение — локальный каталог продуктов, использующий x-ms-webview для обработки заказа пользователя на существующем веб-сайте. Чтобы получить более подробную информацию о приложении, посмотрите выступление Джона Хэйзена (John Hazen) на Build — WebView: Bringing the Web to Your App.

Один из способов загрузки веб-содержимого в x-ms-webview — задание атрибута src в HTML-элементе. Задание атрибута src автоматически вызывает метод navigate()и передает ему строку URI с атрибутами.

<x-ms-webview id="webview" src="http://www.bing.com"></x-ms-webview>

Еще один способ загрузки веб-содержимого — вызов navigate() напрямую. Элемент управления x-ms-webview переходит на веб-сайты и загружает их — даже те, которые обычно не загружаются в iframe.

Примечание. Если атрибут src HTML-элемента задан и при загрузке приложения совершается вызов метода navigate, происходит двойная навигация.

Навигация поддерживает различные протоколы для получения доступа как к веб-, так и локальному содержимому. Примеры JavaScript предоставлены для каждого протокола.

Данная таблица содержит различные URI-схемы, поддерживаемые x-ms-webview. Для получения более подробной информации об этих схемах URI посетите портал MSDN.

Схема URIОписание
http://Произвольное веб-содержимое
https://Веб-содержимое через Secure Sockets Layer
ms-appdata:///Содержимое, помещенное в локальную папку приложения
ms-appx-web:///Содержимое, которое разработчик включил в пакет приложения, но которое не нужно рассматривать как веб-содержимое. Этот HTML не имеет доступа к Windows RT API
ms-local-stream://Содержимое, загруженное разработчиком в поток памяти

Навигация по веб-содержимому в JavaScript

// Навигация webview
webview.navigate(new Windows.Foundation.Uri("http://www.msn.com"));
// Навигация к SSL-содержимому
webview.navigate(new Windows.Foundation.Uri(https://www.facebook.com));

Элемент управления navigateWithHttpRequestMessage() позволяет добавлять информацию о HTTP-запросах до навигации. За счет этого сервер получает возможность выполнить действия с запросом, прежде чем вернуть содержимое.

JavaScript — пример с Get

// Создаем URI, описывающий сайт, на который нужно перейти

var siteUrl = new Windows.Foundation.Uri("http://www.msn.com");

// Задаем тип запроса

var httpRequestMessage = new Windows.Web.Http.HttpRequestMessage(Windows.Web.Http.HttpMethod.get, siteUrl);

// Добавляем заголовки для запроса к веб-серверу для проверки кэша

httpRequestMessage.headers.append("Cache-Control", "no-cache");

httpRequestMessage.headers.append("Pragma", "no-cache");

// Навигация WebView с помощью информации из запроса

webview.navigateWithHttpRequestMessage(httpRequestMessage);

JavaScript — пример с Post

// Создаем URI, описывающий сайт, на который нужно перейти

var siteUrl = new Windows.Foundation.Uri("http://www.msn.com");

// Задаем тип запроса

var httpRequestMessage = new Windows.Web.Http.HttpRequestMessage(Windows.Web.Http.HttpMethod.post, siteUrl);

// Задаем данные post

httpRequestMessage.Content = new Windows.Web.Http.HttpStringContent("cookie=abcxyz123");

// Навигация WebView с помощью информации из запроса

webview.navigateWithHttpRequestMessage(httpRequestMessage); webview.navigateWithHttpRequestMessage(httpRequestMessage);

Локальное содержимое

Кроме того, вы можете направить x-ms-webview на локально хранимое содержимое, которое было включено в ваш пакет или загружено в папку local state. Поддержка автономного режима в приложениях обеспечивает оптимальную работу приложения для любых способов взаимодействия пользователя. Наиболее общий сценарий — когда игра должна работать в режиме офлайн.

В других случаях приложению может понадобиться большая производительность при загрузке и отображении содержимого, которую можно достичь только с помощью локального содержимого. Пример подобного сценария — программа для чтения EPUB-файлов.  EPUB 3 форматы поддерживают содержимое HTML 5, CSS и JavaScript, которое с легкостью отображается в элементе управления x-ms-webview. Давайте рассмотрим API, которые можно использовать для загрузки локального содержимого в x-ms-webview.

JavaScript — переход к локальному содержимому

//Переход к содержимому, включенному в пакет appx

webview.navigate("ms-appx-web:///localPage.html");

//Переход к содержимому, хранящемуся в каталоге local state

webview.navigate("ms-appdata:///local/MyAppsLocalFolder/local.html");

JavaScript — переход к локальному содержимому

Простой пример, показанный выше, работает, но вы можете воспользоваться следующим примером для создания простого HTML-файла в каталоге local state.

// Переменные для local storage

var applicationData = Windows.Storage.ApplicationData.current;

var localFolder = applicationData.localFolder;

// Пишем локальный HTML-файл

function writeLocalHTMLThenNavigate() {

localFolder.createFolderAsync("MyAppsLocalFolder", Windows.Storage.CreationCollisionOption.openIfExists).then(function (folder) {

localFolder.createFileAsync("MyAppsLocalFolder\\local.html",

Windows.Storage.CreationCollisionOption.replaceExisting).then(function (htmlFile) {

var html = "<!DOCTYPE html><html><head>";

html += "<title>Local HTML Content</title></head>";

html += "<body><h1>Local HTML Content</h1></body></html>";

Windows.Storage.FileIO.writeTextAsync(htmlFile, html).then(function (e) {

document.getElementById("webview").navigate("ms-appdata:///local/MyAppsLocalFolder/local.html");

});

}).done(function () {

console.log("Local.html file created successfully.");

});

})

}
writeLocalHTMLThenNavigate();

Метод navigateToLocalStreamUri() предоставляет возможность перехвата содержимого до его загрузки в элемент управления. Наиболее общий сценарий использования — декодирование локального содержимого перед отправкой вывода в x-ms-webview. IUriToStreamResolver должен быть написан на C#/VB или C++, так что разработчикам JavaScript нужно включить дополнительный тип проекта для использования этих функций.  В SDK уже есть готовый пример.

Пример: вызов navigateToLocalStreamUri из JavaScript полагается на лежащий в основе код C#, чтобы выполнить возврат потока. Для ознакомления с полным текстом примера обратитесь к SDK.

JavaScript — переход к потоку

function navigateToStreamWithCSResolver() {

var contentUri = document.getElementById("webview").buildLocalStreamUri("NavigateToStream", "simple_example.html");

var uriResolver = new SDK.WebViewSampleCS.StreamUriResolver();

document.getElementById("webview").navigateToLocalStreamUri(contentUri, uriResolver);

}

navigateToString() — создание и отображение динамического HTML часто встречается в приложениях, которым нужно использовать макет HTML для небольшого фрагмента контента, чтобы быстро отобразить его поверх содержимого или расширить возможности встроенной рекламы.

JavaScript — переход к строковому HTML-содержимому

var strHTML = "<!DOCTYPE HTML>";

strHTML += "<HTML>";

strHTML += "<HEAD><TITLE>NavigateToString() Example</TITLE></HEAD>";

strHTML += "<BODY><H1>HTML markup from a string</H1></BODY>";

strHTML += "</HTML>";

webview.navigateToString(strHTML);

Коммуникации от приложения к WebView

Очень часто бывает так, что приложению нужно связаться с веб-содержимым внутри x-ms-webview, чтобы улучшить удобство использования. Вы можете наладить связь между приложением и веб-сайтом, интегрировав такие функции Windows, как панель приложений, чудо-кнопка «Поиск» или чудо-кнопка «Поделиться», для обмена сообщениями между ними.

Использование метода invokeScriptAsync схоже с вызовом postMessage() в элемент . Приложение всегда может вызвать метод invokeScriptAsync в элементе управления, чтобы выполнить скрипт внутри встроенного содержимого. Однако для встроенного содержимого есть определенные ограничения при отправке сообщений с помощью события MSWebViewScriptNotify в родительский контейнер приложения. Host app to webcontent communication graphic .Изображение с коммуникацией между приложением-хостом и веб-содержимымВ данной

Название события DOMОписание
MSWebViewScriptNotifyДанное событие инициализируется, когда страница внутри webview вызывает метод window.external.notify

В таблице показано, как элемент управления webview передает сообщения в родительское приложение.

Схема URIMSWebViewScriptNotify
http://Нет
https://Да*
ms-appdata:///Нет**
ms-appx-web:///Да
ms-local-stream://Да

*Только если ContentURI заданы в Package.appxmanifest

**Может использовать UriResolver для подключения ScriptNotify

webview.addEventListener("MSWebViewScriptNotify", scriptNotify);

function scriptNotify(e) {

// Проверка URI, посылающего оповещение

if (e.callingUri == "https://myUri.com") {

doSomething(e.value);

}

}

JavaScript

var operation = webview.invokeScriptAsync("startAnimation", "500");

operation.oncomplete = function (e) {

console.log(e.target.result);

};

operation.start();

Взаимодействие с содержимым x-ms-webview

*
Увеличить

Изображение демонстрирует вызов метода capturePreviewToBlogAsync для вывода изображения

Теперь вы можете получить снимок содержимого внутри x-ms-webview, встроенного в API. не может отображать произвольный HTML в виде растрового изображения. Однако метод <a href="http://msdn.microsoft.com/en-us/library/windows/apps/dn301835.aspx"> < strong>capturePreviewToBlobAsync()</strong></a> элемента x-ms-webview позволяет получить изображение. <strong>JavaScript</strong>

var operation = webview.capturePreviewToBlobAsync();

operation.oncomplete = function (e) {

var url = window.URL.createObjectURL(e.target.result);

document.getElementById("imagetag").src = url;

};

operation.start();

*
Увеличить

Изображение демонстрирует, как выделенный HTML (текст + изображение) выводится в главное приложение

Вы можете с легкостью обмениваться содержимым из элемента управления x-ms-webview с помощью контракта«Общий доступ Windows». Встроенный API может извлекать содержимое, выбранное пользователем. Это содержимое затем может быть возвращено в ваше приложение для передачи другим приложениям, поддерживающим контракт получателя данных.

JavaScript — получение выбранного пользователем содержимого

var operation = webview.captureSelectedContentToDataPackageAsync();

operation.oncomplete = function (e) {

// Проверка, допустимо ли выделение

if (e.target.result) {

var data = e.target.result.getView();

if (data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.html){

// Данные содержат HTML, так что берем его!

data.getHtmlFormatAsync().then(function (htmlFormat) {

var htmlFragment = Windows.ApplicationModel.DataTransfer.HtmlFormatHelper.getStaticFragment(htmlFormat);

document.getElementById("output").innerHTML = htmlFragment;

});

}

}

};

operation.start();

Хотите узнать больше?

Как вы видите, элемент x-ms-webview — это мощный инструмент для отображения веб-содержимого в приложениях на HTML и JS. Если у вас уже есть приложение для Windows 8, использующее iframe для встраивания веб-содержимого, я очень советую обновить его и перейти на x-ms-webview в Windows 8.1. А если вы только начинаете создавать приложение, обязательно воспользуйтесь элементом x-ms-webview с самого начала.

Если вы хотите узнать больше об элементе x-ms-webview, посетите следующие замечательные ресурсы:


Ссылка: http://www.oszone.net/25240/