解决 Silverlight 2 中的跨域问题





4.00/5 (1投票)
如何解决 Silverlight 2 中的跨域问题
我们都知道 Silverlight 和 Flash 遵循相似的安全模型,并在浏览器沙箱中运行。这些 RIA 平台本质上会在 RIA 应用程序向 Web 服务发送请求时,请求一个跨域策略文件。如果策略文件不存在,或者没有将您的域名列为允许的域名,那么您有以下选择:
- 致电、写信并要求该公司/个人将您的域名(即,下载您的 Silverlight 应用程序的域名)列为客户端策略文件(clientaccesspolicy.xml 或 crossdomain.xml)中的允许域名——这可能不太合理。
- 创建您自己的代理——该代理将位于您的域名上,并向外部域名发出调用。因此,您的 Silverlight 应用程序将调用同一域名上的代理,从而 Silverlight 运行时将避免请求跨域策略文件。您的代理将简单地调用外部服务,并将响应返回给 Silverlight 应用程序。
- 使用第三方代理服务,而不是自己构建——例如 Yahoo Pipes @ http://pipes.yahoo.com/pipes 或 Google AJAX Feed API @ http://code.google.com/apis/ajaxfeeds。
- 欺骗浏览器,并完全避免使用任何代理。这仅在 Silverlight 应用程序可以访问 HTML Bridge 并将
JavaScript
元素注入到页面的head
标签中时才有效。此外,您需要了解如何将响应传递到 Silverlight 控件。如果您不知道如何实现这一点,那么这种方法将不适合您。我将进一步讨论这个选项,因为其他选项不言自明。
我不确定是否会推荐使用这种方法,因为它感觉像是一种变通方法,但它确实有效。如果,例如,您从与托管 Silverlight 内容的网页不同的域名加载 Silverlight 应用程序 XAP 文件,那么这种方法可能根本不起作用。我不确定 Silverlight 控件是否能够修改宿页面的 head
HTML 元素。
这是您需要实现此技巧的最重要的代码片段:
HtmlElement head = HtmlPage.Document.GetElementsByTagName("head")[0] as HtmlElement; HtmlElement javascriptContent = HtmlPage.Document.CreateElement("script"); javascriptContent.SetProperty("type", "text/javascript"); javascriptContent .SetProperty("src", "http://aWebServiceSomeWhere"); head.AppendChild(javascriptContent);
您看到了这个技巧吗?浏览器的 JavaScript 引擎会说:“哦,看,我们在 header 中添加了一个新的 script
元素,并且它具有 URL 作为 src
属性——我需要下载并 执行 该 JavaScript!”由于请求是由浏览器的 DOM 发起的,与任何 RIA 技术无关,所有传出请求都将成功,并且不会请求任何跨域策略文件。在 JavaScript 返回后,有必要将结果返回给 Silverlight 控件。显然,唯一合理的方法是强制 JavaScript 包含对您的 Silverlight 控件的方法调用。例如,Twitter 允许您在请求中指定 callback=YourJavascriptFunction
,Twitter 服务返回的 JavaScript 结果将包含 YourJavascriptFunction
在响应中。
Bryant Likes 编写了一个 Silverlight Twitter 控件,演示了使用此技巧和使用 Yahoo Pipes 的回退机制。请查看 @ http://blogs.sqlxml.org/bryantlikes/archive/2009/01/23/twilight-a-silverlight-twitter-badge.aspx 和 http://www.codeplex.com/Twilight。
顺便说一下,我目前正在我的博客上使用 Bryant 出色的 Silverlight Twitter badge。