HTML桥无法使用跨域Silverlight XAP



我有一个复杂的Silverlight应用程序,它广泛使用HTML桥接功能(双向)。当托管页面与XAP源来自同一域时,应用程序运行良好。不幸的是,当托管页面在不同的域上时,我无法使HTML桥功能正常工作。

现在,我知道了实现这一点通常需要的各种技巧,即这里记录的所有内容:http://msdn.microsoft.com/en-us/library/cc645023(VS.95).aspx。我甚至整理了我自己的简化跨域repro,我希望它能突出这个问题,但不幸的是,我的"repro"工作正常,即JS->SL和SL->JS功能在其中都很好,即使XAP托管在不同的域上。

以下是我迄今为止试图缩小问题范围的内容:

关于我的生产解决方案(我遇到问题的地方):

  1. 已确认在<object>标记中将"EnableHtmlAccess"设置为true
  2. 已确认在AppManifest.xml文件中将"ExternalCallersFromCrossDomain"设置为"ScriptableOnly"

关于我的repo解决方案(我无法让它出现问题):

  1. 添加了具有多个已注册可脚本化对象的多个库
  2. 已将事件添加到已注册的对象中

在两者上:

  1. 尝试使用静态<object>标记和动态创建的<object>标记(通过Silverlight.js)
  2. 尝试使用和不使用onSourceDownloadProgressChanged、onSourceDownloadComplete、onError和onLoad的处理程序
  3. 试过有没有防溅屏

我有点没主意了。有人对其他故障排除步骤有什么建议吗?

到目前为止,我还无法追踪工作版本和非工作版本之间的确切差异。但我想出了一个变通办法,足以满足我的需求。事实证明,只有JS->SL功能被破坏了;任何来自SL->JS的调用仍然有效。所以我所做的是从Silverlight中注册可编写脚本的SL对象。在我的控制JavaScript类中,我创建了一个具有唯一名称的函数,并将其注册到窗口对象:

var mLoadingController;
var mAppId = 'alantaClient_' + Alanta.makeId();
var mSetLoadingControllerId = mAppId + '_SetLoadingController';
window[mSetLoadingControllerId] = function (value) {
    mLoadingController = value;
    onLoad();
};

然后我将函数的名称作为Silverlight应用程序的InitParams:的一部分传入

var initParams = 'setLoadingControllerId=' + mSetLoadingControllerId;
Silverlight.createObject(mSource, mAppHost, mAppId, params, events, initParams);

然后我从Silverlight中调用注册函数,如下所示:

// Do everything necessary to make the LoadingController scriptable.
HtmlPage.RegisterScriptableObject("LoadingController", LoadingController.Instance);
string setLoadingControllerId;
if (e.InitParams.TryGetValue(LoaderConstants.SetLoadingControllerIdReference, out setLoadingControllerId))
{
    HtmlPage.Window.Invoke(setLoadingControllerId, LoadingController.Instance);
}

然后我可以从JS中调用它,就像这样:

mLoadingController.GoToRoom();

有点粗鲁,但很管用。现在已经足够近了。

最新更新