关闭

Communication Between Hosting System and Its Plugin Applications(Cross Domains)

标签: js-crossdomaineasyXDM
806人阅读 评论(0) 收藏 举报
分类:

Since at the very beginning you need to initiate the whole thing on the hosting app side, so your hosting application should render something like:

<div class="ms_bodyWrap">
	<div class="ms_body dbShop-theme-bodybg" >
		
		<script>
			if(!window.hasInitHostApplicationAddon){
				initHostApplicationAddon('f3f4612484faba346107da36c44e5e24',					
					'http://plugin.system.domain/app.php?shopName=devb06§ion',
					'',	'http:///plugin.system.domain/container.php?container_js_path=http%3A%2F%2Fhost.application.domain%2Fs%2Fv1344%2Fjs%2FhostAppPluginContainerAll.js',
					'http://host.application.domain/swf/easyxdm.swf',			
					'100%',
					'600px',
					'D',
					''
					);

				window.hasInitHostApplicationAddon= true;
			}
		</script>
		<div id="appContainer"  class="app_mainBody dbShop-ui-editArea">
			<div class="dbShop-ui-appLoading" id="dbShop-ui-appLoading" style="display:block;">
				<img src="http://host.application.domain/s/v1344/images/loading_app.gif" /> Loading... 
			</div>
		</div>	
				
	</div>
</div>


It will just present a loading image in the container DIV, and at meanwhile run the javascript function initHostApplicationAddon().


Therefore, initHostApplicationAddon() is the entry point of the entire procedure

function initHostApplicationAddon(shopGuid, iframeUrl, customDomain, containerUrl, swfPath, width, height, deviceType, mode) 
{
	var readyEvent = deviceType == 'M' ? 'pageshow' : 'ready';
	
	$(document).bind(readyEvent, function(){
		var isOpeningDialog = false;
		var hostAppapi = new easyXDM.Rpc(
			/** The configuration */
			{
				swf: swfPath,
				remote: containerUrl,
				container: "appContainer",
				props: {
					scrolling: "no",
					style: {
						width: width,
						height: height,
						border: "0"
					},
					allowTransparency: deviceType=='M' ? "true" : "false"
				},	
			onReady: function(){}
			}, 
		/** The interface configuration */ 
		{
			local:
			{
				onAppReady: function(){

					if(deviceType == 'M'){
						$.mobile.loading('hide');			
					}else{
						$("#dbShop-ui-appLoading").hide();						
					}
				},
				containerReady: function() {
					var data = {src : iframeUrl};
					hostAppapi.redirectIframe(data);
				},
				authen: function(data) {},
				...
			},

			remote:
			{
				redirectIframe: {},
				...
			}
		});
		
		var onAuthCallback = function(data) {};
		...
	
	});
}


Something to highlight:

initHostApplicationAddon() actually attaches a callback function onto the document-ready event, which is anonymous. The function creates the consumer side of easyXDM, and sets up everything, the two most important settings are remote andcontainer, remote is a url of the provider side's page, and container is the id of the DIV which will hold the iFrame later.

So the trick here is that the URL of remote comprises a URL belongs to plugin system domain, but appended with a path of Javascript file, which is actually hosted under host application's domain. And then the next question is what does this container.php in the URL do?

<?php 
	$containerJsPath = isset($_GET['container_js_path']) ? $_GET['container_js_path'] : '';
?>
<script type="text/javascript" src="<?php echo $containerJsPath ?>"></script>
<style>
body {margin:0;}
</style>


It just includes the Js file's URI, with outputting a blank HTML. So, now is the magics inside hostAppPluginContainerAll.js

window.hostAppapi = new easyXDM.Rpc({
	swf: "http://" + baseUrl + "/swf/easyxdm.swf",
	onReady: function()
	{
		iframe = document.createElement("iframe");
		iframe.frameBorder = 0;
		iframe.width = "100%";
		iframe.height = "100%";
		iframe.scrolling = "no";
		document.body.appendChild(iframe);

		hostAppapi.containerReady();
	}
}, {
	local: {
		redirectIframe: function(data) {},
		likeStatusChange: function(data) {},
		...
	},
	remote: {
		onAppReady: {},
		authen: {},
		...
	}
});
})();


It sets up the provider side by creating the easyXDM object with the same name as consumer side (hostAppapi).

As regards the communication between the two parts, it is out of the scope of this article, you can refer to easyXDM official demo:http://consumer.easyxdm.net/current/example/methods.html

Requesting the provider part and setting up the communication channel is also easyXDM's business, so won't be discussed here.

We just need to keep in mind that after the setup procedure is done, onReady() callbacks will be invoked on both consumer & provider sides automatically.

At this point, the HTML should become:

<div class="ms_bodyWrap">
	<div class="ms_body dbShop-theme-bodybg" >
		
		<script>
			if(!window.hasInitHostApplicationAddon){
				initHostApplicationAddon('f3f4612484faba346107da36c44e5e24',					
					'http://plugin.system.domain/app.php?shopName=devb06§ion',
					'',	'http:///plugin.system.domain/container.php?container_js_path=http%3A%2F%2Fhost.application.domain%2Fs%2Fv1344%2Fjs%2FhostAppPluginContainerAll.js',
					'http://host.application.domain/swf/easyxdm.swf',			
					'100%',
					'600px',
					'D',
					''
					);

				window.hasInitHostApplicationAddon= true;
			}
		</script>
		<div id="appContainer"  class="app_mainBody dbShop-ui-editArea">
			<div class="dbShop-ui-appLoading" id="dbShop-ui-appLoading" style="display:block;">
				<img src="http://host.application.domain/s/v1344/images/loading_app.gif" /> Loading... 
			</div>
			
			
			<iframe scrolling="no" frameborder="0" name="easyXDM_default3242_provider" id="easyXDM_default3242_provider" style="width: 100%; height: 568px; border: 0px none;" src="http://plugin.system.domain/container.php?container_js_path=http%3A%2F%2Fhost.application.domain%2Fs%2Fv1344%2Fjs%2FhostAppPluginContainerAll.js&xdm_e=http%3A%2F%2Fhost.application.domain&xdm_c=default3242&xdm_p=1">

				<html>
					<head>
						<script src="http://host.application.domain/s/v1344/js/hostAppPluginContainerAll.js" type="text/javascript"></script>
						<style>
							body {margin:0;}
						</style>
					</head>
					
					<body>

					</body>
				</html>
				
			</iframe>
			
			
		</div>	
				
	</div>
</div>


The process can be illustrated as:



And in our case, we would not make use of this callback on the consumer side, we just use the provider side. Its body includes line:

iframe = document.createElement("iframe");
iframe.frameBorder = 0;
iframe.width = "100%";
iframe.height = "100%";
iframe.scrolling = "no";
document.body.appendChild(iframe);

hostAppapi.containerReady();


Its main responsibility is to create another iFrame (because the easyXDM will create the first iFrame inside the container DIV). And then inform the consumer by calling its API: containerReady().

containerReady: function() {
	var data = {src : iframeUrl};
	hostAppapi.redirectIframe(data);
},

containerReady() will call provider's API redirectIframe(), to make the iFrame redirect to the URL of plugin's entry page. The flow is shown as:



And in the first outputted HTML page of the plugin system, a Javascript from host application domain (hostAppPluginCommon.js) is included:

window.shop88api = parent.shop88api;
window.onload= function (){
	hostAppapi.onAppReady();
};

At the point it calles onAppReady() method of consumer, and what it does is to hide and remove the loading animation.

By now, the initiation process is completed, and onward the Js inside the provider iFrame can call any method that consumer exposes and vice versa.


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:279705次
    • 积分:6527
    • 等级:
    • 排名:第3812名
    • 原创:372篇
    • 转载:1篇
    • 译文:19篇
    • 评论:153条
    最新评论