65.9K
CodeProject 正在变化。 阅读更多。
Home

解决 Silverlight 2 中的跨域问题

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (1投票)

2009年5月2日

Ms-PL

3分钟阅读

viewsIcon

17344

如何解决 Silverlight 2 中的跨域问题

我们都知道 Silverlight 和 Flash 遵循相似的安全模型,并在浏览器沙箱中运行。这些 RIA 平台本质上会在 RIA 应用程序向 Web 服务发送请求时,请求一个跨域策略文件。如果策略文件不存在,或者没有将您的域名列为允许的域名,那么您有以下选择:

  • 致电、写信并要求该公司/个人将您的域名(即,下载您的 Silverlight 应用程序的域名)列为客户端策略文件(clientaccesspolicy.xmlcrossdomain.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.aspxhttp://www.codeplex.com/Twilight

顺便说一下,我目前正在我的博客上使用 Bryant 出色的 Silverlight Twitter badge。

© . All rights reserved.