Script Notify 是否有解决方法不适用于 UWP ms-appdata
Is there a workaround for Script Notify not working on UWP ms-appdata
我正在为 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:
This was a policy decision we made that we have had feedback on so we
re-evaluate it. The same restriction doesn't apply if you use
NavigateToStreamUri together with a resolver object. Internally that's
what happens with ms-appdata:/// anyway.
然后我尝试了在这种情况下建议的方法,即使用此处提到的解析器:
但这对性能有很大影响,因为它不断地将所有文件转换为流以加载,并且某些页面加载不正确。
然后我查看了使用 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) { }
但这也行不通。
那么有没有办法解决这个荒谬的限制?
所以我找到了这个答案:C# class attributes not accessible in Javascript
它说:
I believe you need to define the method name starting with a lower
case character.
For example: change GetIPAddress to getIPAddress.
I tested it on my side and found if I use the upper case name
'GetIPAddress', it won't work. But if I use getIPAddress, it works.
所以我尝试了这个:
我按照建议创建了一个 Windows Runtime Component
类型的新项目 here 并将我的方法名称更改为小写,因此我有:
[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);
}
}
这成功了!
我正在为 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:
This was a policy decision we made that we have had feedback on so we re-evaluate it. The same restriction doesn't apply if you use NavigateToStreamUri together with a resolver object. Internally that's what happens with ms-appdata:/// anyway.
然后我尝试了在这种情况下建议的方法,即使用此处提到的解析器:
但这对性能有很大影响,因为它不断地将所有文件转换为流以加载,并且某些页面加载不正确。
然后我查看了使用 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) { }
但这也行不通。
那么有没有办法解决这个荒谬的限制?
所以我找到了这个答案:C# class attributes not accessible in Javascript
它说:
I believe you need to define the method name starting with a lower case character.
For example: change GetIPAddress to getIPAddress.
I tested it on my side and found if I use the upper case name 'GetIPAddress', it won't work. But if I use getIPAddress, it works.
所以我尝试了这个:
我按照建议创建了一个 Windows Runtime Component
类型的新项目 here 并将我的方法名称更改为小写,因此我有:
[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);
}
}
这成功了!