0

在进行 Silverlight 与 JavaScript 的互操作性时,我在 Silverlight 浏览器外 (OOB) 应用程序中遇到了一个奇怪的行为。我的目标是将一些数据 http-post 到特定站点。我们可以使用 WebClient 或 HTTPWebRequest 类发布数据。但是如何将响应重定向到外部网络浏览器?我想我会用 post 方法生成一个动态 HTML 表单,并从 Silverlight 调用一个 JavaScript 函数来提交表单。不幸的是,它只提交带有 target="_self" 的表单,而不是带有 target="_blank" 的表单。将生成的 html 字符串加载到 Silverlight 的 WebBrowser 控件的代码:

WebBrowser wb = parameter as WebBrowser;
if (wb == null)
    return;

wb.NavigateToString(GetHtml());

生成 HTML 的简单测试方法:

private string GetHtml ()
{
    StringBuilder sb = new StringBuilder ();
    sb.Append ("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
    sb.Append ("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
    sb.Append ("<head><title></title>");
    sb.Append(
        "<script type=\"text/javascript\">function submitForm(){" +
        "document.forms[0].submit(); window.external.notify(\"Form Submitted!\");}</script>");
    sb.Append("</head>");
    sb.Append ("<body>");
    sb.Append ("<form id=\"mainForm\" name=\"formName1\" action=\"http://localhost:53222/ReceivePost.aspx\" method=\"POST\" target=\"_blank\">");
    sb.Append ("<input type=\"text\" name=\"u\" value=\"username\"/>");
    sb.Append ("<input type=\"password\" name=\"p\" value=\"password\"/>");
    sb.Append ("<input type=\"submit\" value=\"Submit\"/>");
    sb.Append("</form>");
    sb.Append("</body></html>");
    return sb.ToString ();
}

生成这样的 HTML 页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script type="text/javascript">
            function submitForm(){
                document.forms[0].submit();
                window.external.notify("Form Submitted!");
            }
        </script>
    </head>
    <body>
        <form id="mainForm" name="formName1" action="http://localhost:53222/ReceivePost.aspx" method="POST" target="_blank">
            <input type="text" name="u" value="username"/>
            <input type="password" name="p" value="password"/>
            <input type="submit" value="Submit"/>
        </form>
    </body>
</html>

以及调用JS函数的代码:

innerWebBrowser.ScriptNotify += (o, args) =>
    {
        MessageBox.Show("JS says: " + args.Value);
    };
innerWebBrowser.InvokeScript ("submitForm");

正如我所说,此代码适用于目标设置为“_self”,但不适用于目标设置为“_blank”。即使我用鼠标按下提交按钮,也不会发送发布数据,只是网站在没有发布数据的外部浏览器中呈现。是因为 Silverlight 中的安全机制吗?我还应该提到,我正在发布 Silverlight 应用程序的同一站点:(http://localhost:53222它还没有发布,因为我直接从 VisualStudio 以 OOB 模式运行它)。因此,我猜它不应该被归类为跨站点脚本......

有没有办法将数据发布到某个网站(不一定来自同一个域)并将响应重定向到外部浏览器?

无论如何,您的意见是最受欢迎的。

4

1 回答 1

0

我想出了一个解决方法,它完全符合我的要求(启动外部浏览器并加载特定的网站,同时向其发布一些参数)。而不是使用WebBrowser带有表单的控制 HTML 文件(类似于问题中的)和 JavaScript 来提交表单onLoad事件。然后将生成的 HTML 内容写入文件系统,稍后使用默认浏览器启动。

可以使用类似的代码创建文件:

using (StreamWriter file = File.CreateText (filePath))
{
    file.WriteLine (GetHtml());
    file.Close ();
}

默认浏览器可以使用类似以下代码的内容打开:

using (dynamic shell = AutomationFactory.CreateObject ("WScript.Shell"))
{
    shell.Run (filePath, 7, false);
}

在默认浏览器启动并运行后,我们可以删除刚刚生成的文件:

if (File.Exists (filePath))
{
    File.Delete (filePath);
}

请注意,为了创建/删除文件,您的 SL 应用程序需要是受信任的应用程序。也就是说,它必须具有提升的权限(检查Application.Current.HasElevatedPermissions属性)。

在 Silverlight 5 中访问本地文件系统。在 SL 4 中,可以使用 com 互操作性并Scripting.FileSystemObject访问本地文件系统。

于 2013-05-24T08:45:24.523 回答