zoukankan      html  css  js  c++  java
  • 背水一战 Windows 10 (64)

    [源码下载]


    背水一战 Windows 10 (64) - 控件(WebView): 加载指定 HttpMethod 的请求, 自定义请求的 http header, app 与 js 的交互



    作者:webabcd


    介绍
    背水一战 Windows 10 之 控件(WebView)

    • 加载指定 HttpMethod 的请求
    • 自定义请求的 http header
    • app 与 js 的交互



    示例
    1、演示 WebView 如何加载指定 HttpMethod 的请求以及如何自定义请求的 http header
    WebApi/Controllers/WebViewPostController.cs

    /*
     * 用于 WebView 演示“如何加载指定 HttpMethod 的请求,以及如何自定义请求的 http header”
     */
    
    using System.IO;
    using System.Linq;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web.Http;
    
    namespace WebApi.Controllers
    {
        public class WebViewPostController : ApiController
        {
            [HttpPost]
            public async Task<HttpResponseMessage> Post()
            {
                Stream stream = await this.Request.Content.ReadAsStreamAsync();
                StreamReader sr = new StreamReader(stream);
                string postData = sr.ReadToEnd();
                sr.Dispose();
    
                string myHeader = this.Request.Headers.GetValues("myHeader").FirstOrDefault();
    
                HttpResponseMessage result = new HttpResponseMessage
                {
                    Content = new StringContent($"post data: {postData}<br /> myHeader: {myHeader}", Encoding.UTF8, "text/html")
                };
    
                return result;
            }
        }
    }

    Controls/WebViewDemo/WebViewDemo3.xaml

    <Page
        x:Class="Windows10.Controls.WebViewDemo.WebViewDemo3"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Windows10.Controls.WebViewDemo"
        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="10 0 0 0">
    
                <WebView Name="webView" Width="800" Height="300" HorizontalAlignment="Left" />
    
            </StackPanel>
        </Grid>
    </Page>

    Controls/WebViewDemo/WebViewDemo3.xaml.cs

    /*
     * WebView - 内嵌浏览器控件(继承自 FrameworkElement, 请参见 /Controls/BaseControl/FrameworkElementDemo/)
     *     
     *     
     * 本例用于演示 
     * 1、WebView 如何加载指定 HttpMethod 的请求
     * 2、WebView 如何自定义请求的 http header
     */
     
    using System;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.Web.Http;
    
    namespace Windows10.Controls.WebViewDemo
    {
        public sealed partial class WebViewDemo3 : Page
        {
            public WebViewDemo3()
            {
                this.InitializeComponent();
    
                this.Loaded += WebViewDemo3_Loaded;
            }
    
            private void WebViewDemo3_Loaded(object sender, RoutedEventArgs e)
            {
                // 实例化 HttpRequestMessage(可以指定请求的 HttpMethod 以及自定义请求的 http header)
                HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri("http://localhost:44914/api/webviewpost"));
    
                // 构造 post 数据
                httpRequestMessage.Content = new HttpStringContent("hello webabcd");
    
                // 自定义 http header
                httpRequestMessage.Headers.Append("myHeader", "hello header");
    
                // 通过 NavigateWithHttpRequestMessage 加载指定的 HttpRequestMessage 对象
                webView.NavigateWithHttpRequestMessage(httpRequestMessage);
            }
        }
    }


    2、演示 app 与 js 的交互
    MyRuntimeComponent/JS2WRC.cs

    /*
     * 用于演示 javascript 调用 windows runtime component 中定义的方法
     */
    
    using Windows.Foundation.Metadata;
    
    namespace MyRuntimeComponent
    {
        [AllowForWeb] // 允许 js 调用
        public sealed class JS2WRC // 注意:在 winrc 中用 c# 写的类必须是 sealed 的
        {
            public string hello(string name)
            {
                return $"hello: {name}";
            }
        }
    }

    Controls/WebViewDemo/WebViewJavaScript.html

    <!--此 html 用于演示 app 与 js 间的交互-->
    
    <!doctype html>
    <html>
    <head>
        <title>i am title</title>
        <script type='text/javascript'>
    
            // app 调用 js 函数
            function appToJs(name) {
                return 'app to js: ' + name;
            }
    
            // js 传递数据到 app
            function jsToApp() {
                window.external.notify('js to app');
            }
    
            // js 调用 wrc
            function jsToWRC() {
                if (window.js2wrc_object) {
                    // js 调用 wrc(在 windows runtime component 中定义的方法)
                    var result = js2wrc_object.hello("webabcd");
                    document.getElementById("div").innerHTML = result;
                }
            }
    
            // 弹出 alert 框
            function showAlert() {
                // 在 uwp 的 webview 中是不能弹出 alert 框的(可以在 c# 中拐弯抹角的实现,参见本例的 c# 端的代码)
                alert("hello: alert");
            }
    
        </script>
    </head>
    <body>
        
        <p>
            <input type='button' onclick='jsToApp();' value='js 传递数据到 app' />
        </p>
    
        <p>
            <input type='button' onclick='jsToWRC();' value='js 调用 wrc' />
        </p>
    
        <p>
            <div id="div"></div>
        </p>
    
        <p>
            <input type='button' onclick='showAlert();' value='弹出 alert 框' />
        </p>
        
    </body>
    </html>

    Controls/WebViewDemo/WebViewDemo4.xaml

    <Page
        x:Class="Windows10.Controls.WebViewDemo.WebViewDemo4"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Windows10.Controls.WebViewDemo"
        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="10 0 10 10">
    
                <TextBlock Name="lblMsg" Margin="5" />
    
                <Button Name="btnAppToJavaScript" Content="app 调用 WebView 加载的 html 中的 JavaScript 函数" Click="btnAppToJavaScript_Click" Margin="5" />
    
                <Button Name="btnEval" Content="通过 eval 访问 DOM" Click="btnEval_Click" Margin="5" />
    
                <Button Name="btnRegisterJavaScript" Content="通过 eval 向 html 注册 JavaScript 脚本" Click="btnRegisterJavaScript_Click" Margin="5" />
    
                <!--
                    通过 ms-appx-web 加载包内的 html 页面
                -->
                <WebView Name="webView" Width="480" Height="320" Source="ms-appx-web:///Controls/WebViewDemo/WebViewJavaScript.html" HorizontalAlignment="Left" Margin="5" 
                         NavigationStarting="WebView_NavigationStarting" NavigationCompleted="WebView_NavigationCompleted" />
    
            </StackPanel>
        </Grid>
    </Page>

    Controls/WebViewDemo/WebViewDemo4.xaml.cs

    /*
     * WebView - 内嵌浏览器控件(继承自 FrameworkElement, 请参见 /Controls/BaseControl/FrameworkElementDemo/)
     *     InvokeScriptAsync() - 调用指定的 js 函数,并返回 js 函数的返回值
     *     ScriptNotify - 收到 js 通过 window.external.notify('') 传递过来的数据时触发的事件
     *     AllowedScriptNotifyUris - 允许触发 ScriptNotify 事件的 uri 列表
     *     AddWebAllowedObject() - 将 windows runtime component 中定义的对象注册到 WebView 加载的页面(需要在 WebView 的 NavigationStarting 事件中调用)
     *
     * 
     * 本例用于演示
     * 1、app 与 js 的交互
     * 2、如何将 windows runtime component 中定义的对象注册到 WebView 加载的页面,以便通过 js 调用 wrc
     */
    
    /*
     * 特别注意:各种 uri schema 对于 ScriptNotify 的支持情况如下
     * 1、http:// 不支持
     * 2、https:// 支持,需要在 appxmanifest 中设置允许的 URI(http 的不行,只能是 https 的),也可以通过 WebView 的 AllowedScriptNotifyUris 属性来设置或获取
     *    <ApplicationContentUriRules>
     *       <Rule Match="https://aaa.aaa.aaa" Type="include" />
     *    </ApplicationContentUriRules>
     * 3、ms-appdata:/// 不支持
     * 4、ms-appx-web:/// 支持
     * 5、ms-local-stream:// 支持
     */
    
    using System;
    using System.Collections.Generic;
    using Windows.UI;
    using Windows.UI.Popups;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    namespace Windows10.Controls.WebViewDemo
    {
        public sealed partial class WebViewDemo4 : Page
        {
            public WebViewDemo4()
            {
                this.InitializeComponent();
    
                webView.ScriptNotify += webView_ScriptNotify;
                webView.NavigationCompleted += webView_NavigationCompleted;
    
                // 由于本例的 webview 是在 xaml 中声明并指定需要加载的 html 的,所以对于 NavigationStarting 事件的注册来说要在 xaml 做
                // webView.NavigationStarting += WebView_NavigationStarting;
            }
    
            void webView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
            {
                if (args.IsSuccess)
                {
                    // 获取 html 标题
                    lblMsg.Text = "html title: " + webView.DocumentTitle;
                    lblMsg.Text += Environment.NewLine;
    
                    // 获取或设置 html 背景色
                    webView.DefaultBackgroundColor = Colors.Orange;
                    lblMsg.Text += "html backgroundColor: " + webView.DefaultBackgroundColor.ToString();
                }
            }
    
            // 收到 js 通过 window.external.notify('') 传递过来的数据时触发的事件
            private async void webView_ScriptNotify(object sender, NotifyEventArgs e)
            {
                // e.Value - 获取 js 传递过来的数据
                // e.CallingUri - 触发此事件的页面的 uri
    
                if (e.Value.StartsWith("alert:"))
                {
                    // 模拟弹出页面的 alert 框(参见下面的 WebView_NavigationCompleted 中的代码)
                    await new MessageDialog(e.Value.Substring(6), "alert").ShowAsync();
                }
                else
                {
                    await new MessageDialog(e.CallingUri.ToString() + " " + e.Value).ShowAsync();
                }
            }
    
            // app 调用 js
            private async void btnAppToJavaScript_Click(object sender, RoutedEventArgs e)
            {
                List<string> arguments = new List<string> { "webabcd" };
                // 调用 js 方法:sayHelloToJs('webabcd'); 并返回结果
                string result = await webView.InvokeScriptAsync("appToJs", arguments);
    
                await new MessageDialog(result).ShowAsync();
            }
    
            // 通过 eval 访问 DOM
            private async void btnEval_Click(object sender, RoutedEventArgs e)
            {
                // 设置 document.title 的值(用于演示如何通过 eval 设置 DOM)
                List<string> arguments = new List<string> { "document.title = 'hahaha';" };
                await webView.InvokeScriptAsync("eval", arguments);
    
                // 获取 document.title 的值(用于演示如何通过 eval 获取 DOM)
                arguments = new List<string> { "document.title;" };
                string result = await webView.InvokeScriptAsync("eval", arguments);
                await new MessageDialog(result).ShowAsync();
            }
    
            // 通过 eval 向 html 注册 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();
            }
    
            // js 调用 wrc
            private void WebView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
            {
                // 注意:需要在 WebView 的 NavigationStarting 事件中调用 AddWebAllowedObject()
                webView.AddWebAllowedObject("js2wrc_object", new MyRuntimeComponent.JS2WRC());
            }
    
            // 模拟弹出页面的 alert 框
            private async void WebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
            {
                // 在 uwp 的 webview 中是不能弹出 alert 框的
                // 可以向页面注入脚本重写 window.alert 函数,使其调用 window.external.notify 通知 c# 端,然后弹出 MessageDialog 框以模拟页面的 alert 框(参见上面的 webView_ScriptNotify 中的代码)
                // 在 uwp 的 webview 中也是不能弹出 confirm 框的,也不能像实现 alert 框那样如法炮制,因为 JavaScript 是运行在单线程上的,其不会等待 c# 调用的结果,所以如何实现 confirm 框还是另想办法吧
                await webView.InvokeScriptAsync("eval", new string[] { "window.alert = function (alertMessage) {window.external.notify('alert:' + alertMessage)}" });
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    HDU2586 How far away?(tarjan的LCA)
    You Raise Me Up
    POJ2891 Strange Way to Express Integers(中国剩余定理)
    POJ2142 The Balance(扩展欧几里得)
    HDU 1166模仿大牛写的线段树
    NetWord Dinic
    HDU 1754 线段树裸题
    hdu1394 Minimum Inversion Number
    hdu2795 Billboard
    【完全版】线段树
  • 原文地址:https://www.cnblogs.com/webabcd/p/7541327.html
Copyright © 2011-2022 走看看