【问题标题】:How to Javascript notify() with ms-appdata on Windows 10 UWP如何在 Windows 10 UWP 上使用 ms-appdata 使用 Javascript notify()
【发布时间】:2017-09-14 17:23:57
【问题描述】:

由于文件写入安全问题,我们尝试将我们的应用从使用 ms-appx-web: 切换到使用 ms-appdata:。但是它立即失败了,因为我们依赖 window.external.notify() ,它与 ms-appx-web: 一起工作得很好:但似乎与 ms-appdata: 一起表现为无操作。作为测试,我们将以下 html 加载到 WebView 对象中:

<html>
<head>
    <script>
        function demofunc( str ) {
            document.getElementById("demo").innerHTML += str;
            window.external.notify( str );
        }
    </script>
</head>
<body onLoad="demofunc('demofunc()');">
    demo &lt;body&gt;
    <div id="demo"></div>
</body>
</html>

它应该会产生这个结果:

demo <body> 
demofunc()

但是,不会产生任何类型的弹出消息。为什么?显然,正在调用 demofunc() 方法以在演示 div 中添加第二行输出,但 window.external.notify() 没有产生弹出消息。是否有关于 notify() 和 ms-appdata: 的特殊规则?

更新 - 问题 Can't run javascript alerts in universal app's webview at payment gateway 类似,适用于 ms-appx-web: 但不适用于 ms-appdata:。该问题捕获 ScriptNotify() 然后使用 Windows.UI.Popups.MessageDialog 弹出一个对话框。使用 ms-appx-web:调用 ScriptNotify(),但使用 ms-appdata:不调用 ScriptNotify()。那是我们的问题,没有弹出窗口发生。

【问题讨论】:

标签: javascript windows uwp notify appdata


【解决方案1】:

但它立即失败了,因为我们依赖 window.external.notify(),它与 ​​ms-appx-web 一起工作得很好:但似乎与 ms-appdata: 无操作:。

对于您的方案,请使用方案ms-local-stream:///,而不是ms-appdata:///。我已经测试了ms-local-stream:/// 方案,它运行良好。

要使用NavigateToLocalStreamUri 方法,您必须传入将URI 模式转换为内容流的IUriToStreamResolver 实现。请参考以下代码。

StreamUriWinRTResolver

public sealed class StreamUriWinRTResolver : IUriToStreamResolver
    {
        /// <summary>
        /// The entry point for resolving a Uri to a stream.
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
        {
            if (uri == null)
            {
                throw new Exception();
            }
            string path = uri.AbsolutePath;
            // Because of the signature of this method, it can't use await, so we
            // call into a separate helper method that can use the C# await pattern.
            return getContent(path).AsAsyncOperation();
        }

        /// <summary>
        /// Helper that maps the path to package content and resolves the Uri
        /// Uses the C# await pattern to coordinate async operations
        /// </summary>
        private async Task<IInputStream> getContent(string path)
        {
            // We use a package folder as the source, but the same principle should apply
            // when supplying content from other locations
            try
            {
                Uri localUri = new Uri("ms-appdata:///local" + path);
                StorageFile f = await StorageFile.GetFileFromApplicationUriAsync(localUri);
                IRandomAccessStream stream = await f.OpenAsync(FileAccessMode.Read);
                return stream.GetInputStreamAt(0);
            }
            catch (Exception) { throw new Exception("Invalid path"); }
        }
    }

主页

public MainPage()
 {
     this.InitializeComponent();
     MyWebView.ScriptNotify += MyWebView_ScriptNotify;
     Uri url = MyWebView.BuildLocalStreamUri("MyTag", "/Test/HomePage.html");
     StreamUriWinRTResolver myResolver = new StreamUriWinRTResolver();
     MyWebView.NavigateToLocalStreamUri(url, myResolver);
 }

我已将code sample 上传到 github。请检查。

【讨论】:

  • 谢谢,这确实解决了弹出对话框不显示的问题。显然,UWP 不允许 Javascript 使用 ms-appdata 启动弹出窗口,但允许使用 ms-local-stream。