【问题标题】:Is there a workaround for Script Notify not working on UWP ms-appdata是否有脚本通知无法在 UWP ms-appdata 上运行的解决方法
【发布时间】:2017-07-19 19:05:12
【问题描述】:

我正在为 Xamarin.UWP 开发一个应用程序,它试图将 Javascript 注入本地 html 文件 (uri: ms-appdata:///local/index.html),如下所示:

async void OnWebViewNavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
    if (args.IsSuccess)
    {
        // Inject JS script
        if (Control != null && Element != null)
        {
            foreach (var f in Element.RegisteredFunctions.Where(ff => !ff.IsInjected))
            {
                await Control.InvokeScriptAsync("eval", new[] { string.Format(JavaScriptFunctionTemplate, f.Name) });
                f.Injected();
            }
        }
    }
}

然后当调用 Javascript 方法时,它将调用 OnWebViewScriptNotify 方法,以便我可以在我的应用程序中处理请求。

问题是这对某些kind of security reasons 不起作用:

这是我们做出的一项政策决定,我们收到了反馈,因此我们 重新评估它。如果您使用相同的限制,则不适用 NavigateToStreamUri 和解析器对象。内部是这样 无论如何,ms-appdata:/// 会发生什么。

然后我尝试了在这种情况下的建议,即使用此处提到的解析器:https://stackoverflow.com/a/18979635/2987066

但这会对性能产生巨大影响,因为它会不断将所有文件转换为要加载的流,以及某些页面加载不正确。

然后我研究了使用AddWebAllowedObject 方法,如下所示:

private void Control_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
{
    if (Control != null && Element != null)
    {
        foreach (var f in Element.RegisteredFunctions)
        {
            var communicator = new HtmlCommunicator(f);
            Control.AddWebAllowedObject("HtmlCommunicator", communicator);
        }
    }
}

HtmlCommunicator 在哪里:

[AllowForWeb]
public sealed class HtmlCommunicator
{
    public JSFunctionInjection Function { get; set; }

    public HtmlCommunicator(JSFunctionInjection function)
    {
        Function = function;
    }

    public void Fred()
    {
        var d = 2;
        //Do something with Function
    }
}

在我的 html 中是这样的:

try { window.HtmlCommunicator.Fred(); } catch (err) { }

但这也不起作用。

那么有没有办法解决这个可笑的限制?

【问题讨论】:

标签: javascript c# xamarin uwp xamarin.uwp


【解决方案1】:

所以我找到了这个答案:C# class attributes not accessible in Javascript

上面写着:

我相信您需要定义以较低开头的方法名称 大小写字符。

例如:将 GetIPAddress 更改为 getIPAddress。

我在我这边测试了一下,发现我是否使用大写名称 'GetIPAddress',它不起作用。但如果我使用 getIPAddress,它就可以工作。

所以我尝试了这个:

我按照here 的建议创建了一个Windows Runtime Component 类型的新项目,并将我的方法名称更改为小写,所以我有:

[AllowForWeb]
public sealed class HtmlCommunicator
{
    public HtmlCommunicator()
    {
    }

    public void fred()
    {
        var d = 2;
        //Do something with Function
    }
}

然后在我的 javascript 中:

try { window.HtmlCommunicator.fred(); } catch (err) { }

在我的主要 UWP 项目中,我引用了新的 Windows Runtime Component 库并具有以下内容:

public HtmlCommunicator communicator { get; set; }

private void Control_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
{
    if (Control != null && Element != null)
    {
        communicator = new HtmlCommunicator();
        Control.AddWebAllowedObject("HtmlCommunicator", communicator);
    }
}

这成功了!

【讨论】:

  • 你能不能给出一个小函数,它可以从 HtmlCommunicator 类返回模型,而不考虑 void。
猜你喜欢
  • 2013-09-23
  • 2011-10-30
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-01
  • 2010-10-11
  • 1970-01-01
相关资源
最近更新 更多