代码改变世界

【原】跨域引用Silverlight XAP配置方法

2009-07-07 20:24  拖鞋不脱  阅读(1962)  评论(13编辑  收藏  举报

问题场景

跨域引用Silverlight,即将Silverlight包部署在A域下,却由在B域下的网站引用。其中Silverlight通过HTML.Window调用了脚本方法。

示例代码

public partial class Page : UserControl
{
    public Page()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        HtmlPage.Window.Alert("hi");
    }
}

异常描述

  1. 进入B域页面,没有看到Silverlight展现,右键点击相应区域,显示“Silvelight”,说明Silverlight区域已经被渲染出来。通过HTTP Watch查看,发现Xap包已经被请求并下载下来,但就是没有展现。
  2. Silverlight正常显示,但点击按钮后,并不弹出对话框。调试发现,在HtmlPage.Window.Alert("hi");抛出异常,异常信息为“已禁用DOM/脚本桥”。

问题解决

  1. 加载却不展示,是由于在A网站下没有给Silverlight配置正确的MIME类型。当引用不同域下的Silverlight包,Silverlight Runtime会检测XAP的HTTP头中的MIME类型。正确的类型是“application/x-silverlight-app”,如果配为“application/x-silverlight-2”(这似乎是旧版本的MIME配置),同样不能正常显示。IIS7由于默认带有Xap的MIME类型配置,所以不会出现此类问题。
  2. 不能正常弹出Alert对话框,但如果改成MessageBox.Show("Click");却可以正常运行。这是因为需要配置Silverlight以及Host Silverlight的页面的几个参数,使得Silverlight中的ManagedCode和页面中的Javascript和DOM code可以交互。而在同域下,这几个参数或者是默认配置好的,或者就是干脆无效,所以不需要配置。具体可参考(Security Settings in HTML Bridge),具体到这里的情况,就是要在页面中配置enableHtmlAccess属性,使在Silverlight的Manage code里可以操纵外部Dom对象。
    Asp.net页面:
    <asp:Silverlight ID="Xaml1" HtmlAccess="Enabled"  runat="server"
    Source=http://localhost:2300/ClientBin/SilverlightApplication.xap
    MinimumVersion="2.0.31005.0" Width="100%" Height="100%" />
    HTML页面:
    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="80%" height="80%" >
        <param name="enableHtmlAccess" value="true" />
        <param name="source" value="http://localhost:2300/ClientBin/SilverlightApplication.xap"/>
        <param name="onerror" value="onSilverlightError" />
        <param name="background" value="white" />
        <param name="minRuntimeVersion" value="2.0.31005.0" />
        <param name="autoUpgrade" value="true" />
        <a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
             <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
        </a>
    </object>

其余问题

  1. Silverlight跨域访问Web Service,需要配置策略文件clientaccesspolicy.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <access-policy>
      <cross-domain-access>
        <policy>
          <allow-from http-request-headers="*">
            <domain uri="*"/>
          </allow-from>
          <grant-to>
            <resource path="/" include-subpaths="true"/>
          </grant-to>
        </policy>
      </cross-domain-access>
    </access-policy>
    将其放到Web Service网站根目录下。注意,如果想让Host在Http网站下的Xap包可以请求Https下的Web Service,需要在allow-from 节中添加<domain uri="http://*" />。
  2. 在http网站下似乎无法请求https网站下的Silverlight,只经过实验,没经过推敲。
  3. 如果在IE中,将Host Silverlight的A网站加入“可信站点”,则访问B网站时,即使网页中有引用A网站的Silvelright,但从HttpsWatch中根本没有看到发起对该Silverlight的请求,不请求“可信站点”的原理。