重新想象 Windows 8.1 Store Apps (80) - 控件增強: WebView 之基本應用, POST 數據, 與 JavaScript 交互


[源碼下載]


重新想象 Windows 8.1 Store Apps (80) - 控件增強: WebView 之基本應用, POST 數據, 與 JavaScript 交互



作者:webabcd


介紹
重新想象 Windows 8.1 Store Apps 之控件增強

  • WebView 的基本應用
  • WebView 通過 POST 請求和 HTTP 頭加載 url
  • WebView 與 JavaScript 交互



示例
1、演示 WebView 的基本應用
WebView/Demo.xaml

<Page
    x:Class="Windows81.Controls.WebView.Demo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows81.Controls.WebView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <Button Name="btnNavigateUrl" Content="導航到指定的 url" Click="btnNavigateUrl_Click" />

            <WebView Name="webView" Width="800" Height="2000" HorizontalAlignment="Left" Margin="0 10 0 0" />

        </StackPanel>
    </Grid>

    <Page.BottomAppBar>
        <AppBar x:Name="appBar" IsSticky="True" Padding="10,0">
            <StackPanel Name="buttonPanel" Orientation="Horizontal" HorizontalAlignment="Left">
                <AppBarButton Icon="Play" Label="SymbolIcon" />
            </StackPanel>
        </AppBar>
    </Page.BottomAppBar>
</Page>

WebView/Demo.xaml.cs

/*
 * 本例演示 WebView 的基本應用
 * 
 * WebView - 內嵌瀏覽器
 *     
 * 
 * 提示:
 * 在 win8 中 WebView 會擋住所有元素(包括 AppBar),而在 win8.1 中不會再有這種情況了
 * 如果想看看 win8 中全屏 WebView 如何不擋 AppBar,以及如何使用 WebViewBrush 以達到不遮擋其他元素的目的,請參看:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 * 
 * 注:win8 和 win8.1 中的 WebView 有很多區別,在 win8.1 中使用 WebView 請參考本系列教程,在 win8 中使用 WebView 請看考:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 */

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace Windows81.Controls.WebView
{
    public sealed partial class Demo : Page
    {
        public Demo()
        {
            this.InitializeComponent();
        }

        private void btnNavigateUrl_Click(object sender, RoutedEventArgs e)
        {
            // 導航到指定的 url
            webView.Navigate(new Uri("http://www.sina.com.cn/", UriKind.Absolute));
            // webView.Source = new Uri("http://webabcd.cnblogs.com/", UriKind.Absolute);

            // web 頁面中的某一個 frame 加載前
            webView.FrameNavigationStarting += webView_FrameNavigationStarting;
            // web 頁面中的某一個 frame 加載中
            webView.FrameContentLoading += webView_FrameContentLoading;
            // web 頁面中的某一個 frame 的 DOM 加載完成
            webView.FrameDOMContentLoaded += webView_FrameDOMContentLoaded;
            // web 頁面中的某一個 frame 導航完成(成功或失敗)
            webView.FrameNavigationCompleted += webView_FrameNavigationCompleted;

            // web 頁面加載前
            webView.NavigationStarting += webView_NavigationStarting;
            // web 頁面加載中
            webView.ContentLoading += webView_ContentLoading;
            // web 頁面的 DOM 加載完成
            webView.DOMContentLoaded += webView_DOMContentLoaded;
            // web 頁面導航完成(成功或失敗)
            webView.NavigationCompleted += webView_NavigationCompleted;

            // 當腳本運行時,可能會導致 app 無響應。此事件會定期執行,然后可查看 ExecutionTime 屬性,如果要暫停腳本,則將 StopPageScriptExecution 屬性設置為 true 即可
            webView.LongRunningScriptDetected +=webView_LongRunningScriptDetected;
            // 在 WebView 對 SmartScreen 篩選器報告為不安全的內容顯示警告頁面時發生
            webView.UnsafeContentWarningDisplaying +=webView_UnsafeContentWarningDisplaying;
            // 在 WebView 嘗試下載不受支持的文件時發生
            webView.UnviewableContentIdentified +=webView_UnviewableContentIdentified;


            // 用於導航 web 的一系列 api,顧名思義,不解釋了
            // webView.CanGoBack;
            // webView.GoBack();
            // webView.CanGoForward;
            // webView.GoForward();
            // webView.Stop();
            // webView.Refresh();


            RotateTransform rt = new RotateTransform();
            rt.Angle = 5;
            // 支持 RenderTransform 了
            webView.RenderTransform = rt;

            // 支持 Opacity 了
            webView.Opacity = 0.3;

            // 支持 Focus 了
            // webView.Focus(FocusState.Programmatic);
        }


        void webView_FrameNavigationStarting(Windows.UI.Xaml.Controls.WebView sender, WebViewNavigationStartingEventArgs args)
        {
            // 是否取消此 url 的加載
            // args.Cancel = true;

            // args.Uri
        }
        void webView_FrameContentLoading(Windows.UI.Xaml.Controls.WebView sender, WebViewContentLoadingEventArgs args)
        {
            // args.Uri
        }
        void webView_FrameDOMContentLoaded(Windows.UI.Xaml.Controls.WebView sender, WebViewDOMContentLoadedEventArgs args)
        {
            // args.Uri
        }
        void webView_FrameNavigationCompleted(Windows.UI.Xaml.Controls.WebView sender, WebViewNavigationCompletedEventArgs args)
        {
            // 導航是否成功
            // args.IsSuccess

            // 導航失敗時,失敗原因的 WebErrorStatus 枚舉
            // args.WebErrorStatus
        }
        

        void webView_NavigationStarting(Windows.UI.Xaml.Controls.WebView sender, WebViewNavigationStartingEventArgs args)
        {
            // 是否取消此 url 的加載
            // args.Cancel = true;

            // args.Uri
        }
        void webView_ContentLoading(Windows.UI.Xaml.Controls.WebView sender, WebViewContentLoadingEventArgs args)
        {
            // args.Uri
        }
        void webView_DOMContentLoaded(Windows.UI.Xaml.Controls.WebView sender, WebViewDOMContentLoadedEventArgs args)
        {
            // args.Uri
        }
        void webView_NavigationCompleted(Windows.UI.Xaml.Controls.WebView sender, WebViewNavigationCompletedEventArgs args)
        {
            // 導航是否成功
            // args.IsSuccess

            // 導航失敗時,失敗原因的 WebErrorStatus 枚舉
            // args.WebErrorStatus
        }


        // 在 WebView 嘗試下載不受支持的文件時發生
        void webView_UnviewableContentIdentified(Windows.UI.Xaml.Controls.WebView sender, WebViewUnviewableContentIdentifiedEventArgs args)
        {
            // 引用頁
            // args.Referrer

            // args.Uri
        }

        // 在 WebView 對 SmartScreen 篩選器報告為不安全的內容顯示警告頁面時發生
        void webView_UnsafeContentWarningDisplaying(Windows.UI.Xaml.Controls.WebView sender, object args)
        {
            
        }

        // 當腳本運行時,可能會導致 app 無響應。此事件會定期執行,然后可查看 ExecutionTime 屬性,如果要暫停腳本,則將 StopPageScriptExecution 屬性設置為 true 即可
        void webView_LongRunningScriptDetected(Windows.UI.Xaml.Controls.WebView sender, WebViewLongRunningScriptDetectedEventArgs args)
        {
            // 獲取 WebView 執行的一個長時間運行的腳本的運行時間(單位:毫秒)
            // args.ExecutionTime

            // 是否暫停在 WebView 中執行的已運行很長時間的腳本
            // args.StopPageScriptExecution
        }
    }
}


2、演示如何通過 POST 請求和 HTTP 頭加載 url
WebView/Post.xaml

<Page
    x:Class="Windows81.Controls.WebView.Post"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows81.Controls.WebView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <WebView Name="webView" Width="800" Height="300" HorizontalAlignment="Left" />

        </StackPanel>
    </Grid>

</Page>

WebView/Post.xaml.cs

/*
 * 本例演示如何通過 POST 請求和 HTTP 頭加載 url
 * 
 * WebView - 內嵌瀏覽器
 *     
 * 
 * 提示:
 * 在 win8 中 WebView 會擋住所有元素(包括 AppBar),而在 win8.1 中不會再有這種情況了
 * 如果想看看 win8 中全屏 WebView 如何不擋 AppBar,以及如何使用 WebViewBrush 以達到不遮擋其他元素的目的,請參看:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 * 
 * 注:win8 和 win8.1 中的 WebView 有很多區別,在 win8.1 中使用 WebView 請參考本系列教程,在 win8 中使用 WebView 請看考:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 */

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.Web.Http;

namespace Windows81.Controls.WebView
{
    public sealed partial class Post : Page
    {
        public Post()
        {
            this.InitializeComponent();

            this.Loaded += Post_Loaded;
        }

        void Post_Loaded(object sender, RoutedEventArgs e)
        {
            HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri("http://localhost:39630/WebViewPost.aspx")); // 此測試 aspx 在 WebServer 項目中

            // 構造 post 數據(無法 form 提交,因為試了很久,無法將 ContentType 設置為 "application/x-www-form-urlencoded")
            httpRequestMessage.Content = new HttpStringContent("hello webabcd");

            // 構造 http header 數據
            httpRequestMessage.Headers.Append("myHeader", "hello header");

            // NavigateWithHttpRequestMessage() - 通過 POST 請求和 HTTP 頭加載 url
            webView.NavigateWithHttpRequestMessage(httpRequestMessage);
        }
    }
}

服務端:
WebServer/WebViewPost.aspx.cs

/*
 * 用於 WebView 演示如何通過 POST 請求和 HTTP 頭加載 url
 */

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebServer
{
    public partial class WebViewPost : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Request.InputStream.Position = 0;
            StreamReader str = new StreamReader(Request.InputStream);
            string postData = str.ReadToEnd();
            str.Dispose();

            // 顯示 post 過來的數據
            Response.Write("post data: " + postData);
            Response.Write("<br />");
            // 顯示請求的一個自定義的 http 頭
            Response.Write("my header: " + Request.Headers["myHeader"]);
        }
    }
}


3、演示 WebView 如何與 JavaScript 交互
WebView/Interact.xaml

<Page
    x:Class="Windows81.Controls.WebView.Interact"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows81.Controls.WebView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <TextBlock Name="lblMsg" FontSize="14.667" />
            
            <Button Name="btnInvokeJavaScript" Content="app 調用 WebView 加載內容中的 JavaScript 函數" Click="btnInvokeJavaScript_Click" Margin="0 10 0 0" />

            <Button Name="btnAccessDOM" Content="通過 eval 訪問 DOM" Click="btnAccessDOM_Click" Margin="0 10 0 0" />

            <Button Name="btnRegisterJavaScript" Content="通過 eval 向頁面中注冊 JavaScript 腳本" Click="btnRegisterJavaScript_Click" Margin="0 10 0 0" />

            <!--
                通過 ms-appx-web 加載包內的 html 頁面
            -->
            <WebView Name="webView" Width="400" Height="300" Source="ms-appx-web:///Controls/WebView/WebViewInteract.html" HorizontalAlignment="Left" Margin="0 10 0 0" />

        </StackPanel>
    </Grid>
</Page>

WebView/Interact.xaml.cs

/*
 * 本例演示 WebView 如何與 JavaScript 交互
 * 
 * WebView - 內嵌瀏覽器
 *     DocumentTitle - html 中的 title
 *     DefaultBackgroundColor - html 中的背景色
 *     InvokeScriptAsync() - 調用 JavaScript 中的指定函數,並返回執行結果
 *     ScriptNotify - 當接收到從 JavaScript 發過來的數據時所觸發的事件(事件參數:NotifyEventArgs),通過在 html 中調用 window.external.notify 來實現 js 調用 app
 *     
 * NotifyEventArgs
 *     Value - js 傳遞給 app 的數據
 * 
 * 本例通過加載同目錄下的 WebViewInteract.html 來演示 app 與 js 的交互
 * 
 * 
 * 
 * 提示:
 * 在 win8 中 WebView 會擋住所有元素(包括 AppBar),而在 win8.1 中不會再有這種情況了
 * 如果想看看 win8 中全屏 WebView 如何不擋 AppBar,以及如何使用 WebViewBrush 以達到不遮擋其他元素的目的,請參看:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 *
 * 注:win8 和 win8.1 中的 WebView 有很多區別,在 win8.1 中使用 WebView 請參考本系列教程,在 win8 中使用 WebView 請看考:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 */

/*
 * 特別注意:
 * 1、在 win8.1 中如果要允許外部網頁引發 ScriptNotify 事件,則必須在 appxmanifest 中設置允許的 URI,必須是 https 協議的,類似如下
 *    <ApplicationContentUriRules>
 *       <Rule Match="https://aaa.aaa.aaa" Type="include" />
 *    </ApplicationContentUriRules>
 * 2、如果使用的是本地 html 數據則無此限制,比如通過 NavigateToString 或 ms-appx-web 來加載 html 時
 * 3、另外如果是 http 的話,可以將 html 下載到本地,然后加載此 html,而 html 中的 url 引用則可以引用遠程的(如果需要替換 html 中的 url 引用則可以參考 Local.xaml 的方式)
 */

using System;
using System.Collections.Generic;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Windows81.Controls.WebView
{
    public sealed partial class Interact : Page
    {
        public Interact()
        {
            this.InitializeComponent();

            webView.ScriptNotify += webView_ScriptNotify;
            webView.NavigationCompleted += webView_NavigationCompleted;
        }

        void webView_NavigationCompleted(Windows.UI.Xaml.Controls.WebView sender, WebViewNavigationCompletedEventArgs args)
        {
            if (args.IsSuccess)
            {
                lblMsg.Text = "html title: " + webView.DocumentTitle;
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += "html backgroundColor: " + webView.DefaultBackgroundColor.ToString();
            }
        }

        async void webView_ScriptNotify(object sender, NotifyEventArgs e)
        {
            // 獲取 js 傳遞過來的數據(js 端通向 app 傳遞數據的方法:window.external.notify('js to app');)
            await new MessageDialog(e.Value).ShowAsync();
        }

        // app 調用 js
        private async void btnInvokeJavaScript_Click(object sender, RoutedEventArgs e)
        {
            List<string> arguments = new List<string> { "webabcd" };
            // 調用 js 方法:sayHelloToJs('webabcd'); 並返回結果
            string result = await webView.InvokeScriptAsync("sayHelloToJs", arguments);

            await new MessageDialog(result).ShowAsync();
        }

        // 通過 eval 方式訪問 DOM
        private async void btnAccessDOM_Click(object sender, RoutedEventArgs e)
        {
            // 獲取 document.title 的值
            List<string> arguments = new List<string> { "document.title" };
            string result = await webView.InvokeScriptAsync("eval", arguments);

            await new MessageDialog(result).ShowAsync();
        }

        // 通過 eval 向頁面中注冊 JavaScript 腳本
        private async void btnRegisterJavaScript_Click(object sender, RoutedEventArgs e)
        {
            // 向 html 中注冊腳本
            List<string> arguments = new List<string> { "function xxx(){return '由 app 向 html 注冊的腳本返回的數據';}" };
            await webView.InvokeScriptAsync("eval", arguments);

            // 調用剛剛注冊的腳本
            string result = await webView.InvokeScriptAsync("xxx", null);

            await new MessageDialog(result).ShowAsync();
        }
    }
}

HTML:
WebView/WebViewInteract.html

<!--此 html 用於演示 app 與 js 間的交互-->

<!doctype html>
<html>
<head>
    <title>I am html title</title>
    <script type='text/javascript'>
        function sayHelloToJs(name) {
            return 'app to js: ' + name;
        }

        function sayHelloToApp() {
            // 傳遞數據給 app
            window.external.notify('js to app');
        }
    </script>
</head>
<body>
    <input type='button' onclick='sayHelloToApp();' value='js 調用 app 中的方法' />
</body>
</html>



OK
[源碼下載]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM