Lesson 21: Interacting with an additional IFrame

From VZ Developer Wiki
Jump to: navigation, search

General Guidelines | XML Specification | Features | Views | JavaScript API | REST API | Tutorials | OAuth


Lesson 20: Post on a user's wall Back to overview Lesson 22: Posting a status update for an user

In some cases you would like to interact with an additional IFrame that you embed into your gadget but is hosted on another domain. An example would be the inclusion of your payment provider's payment flow directly into your gadget: When you want to bill the user you open an IFrame with your payment provider's interface into your gadget. After the user finishes the payment flow, the payment provider interface in the IFrame can interact with its parent (the gadget), and call a method that closes the IFrame. Both gadget and payment interface are hosted and separate domains, so you can not call the method of the parent frame directly because of browser security restrictions. As a solution you can use the gadgets.rpc package offered by the VZ-Gadget Server.

In your gadget you have to add code to open the IFrame and register a callback method for rpc access which closes the IFrame:

<Content type="html"><![CDATA[
  <script type="text/javascript">
   function getEnv() {
      return '__ENV_CONTAINER__';
   }

   function fillIframe() {
        var rpcToken = gadgets.util.getUrlParameters()['rpctoken'];
	var url = 'http://localhost:8062/backends/xdtest/xd.html?rpctoken=' + rpcToken;
	url += '&env=' + getEnv();
        url += '&parent=' + encodeURIComponent('http://' + location.host);
	var iframe = document.getElementById('myiframe');
	iframe.src = url;
        gadgets.rpc.setAuthToken('myiframe', rpcToken);
        gadgets.rpc.setRelayUrl('myiframe', 'http://localhost:8062/backends/xdtest/rpc_relay.html');
   }

   gadgets.util.registerOnLoadHandler(function() {
      gadgets.rpc.register('frameCallback', function (args) {
	  alert("received arguments: " + args);
          this.callback('callbackValue');
      });
   });

  </script>
  <iframe id="myiframe" name="myiframe"></iframe>
  <a href="javascript:;" onclick="fillIframe();">fill iframe</a>
]]></Content>

The name attribute of the iframe is important, because otherwise receiving a callback in the iframe will not be possible in some browsers.

In your payment interface side you have to include the following JavaScript file:

http://studivz.gadgets.apivz.net/gadgets/js/rpc.js

In order to be able to receive callbacks from the gadget in your iframe you have to download this relay file

http://studivz.gadgets.apivz.net/gadgets/files/container/rpc_relay.html

and place it on the same host, where your iframe target lies.

The following HTML Site just shows some content and then makes a rpc call to the fameCallback method of the gadget:

<html> 
<head> <title>Cross-Domain Receiver Page</title> </head> 
<body>
Some Content
<script src="http://studivz.gadgets.apivz.net/gadgets/js/rpc.js" type="text/javascript"></script>

<script type="text/javascript">

	function getURLParameter(name)
	{ 
	     name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); 
	     var regexS = "[\\?&]"+name+"=([^&#]*)"; 
	     var regex = new RegExp( regexS ); 
	     var results = regex.exec( window.location.href ); 
	     if( results == null ) return ""; 
	     else return unescape(results[1]); 
	}  


   	window.onload = function () {

	var env = getURLParameter('env');
		
	var relayURL = 'http://';
		
	switch (env) {
            case 'sandbox':
		relayURL += 'sandbox.gadgets.apivz.net';
		break;
    	    case 'svz':
    		relayURL += 'studivz.gadgets.apivz.net';
    		break;
    	    case 'avz':
    		relayURL += 'meinvz.gadgets.apivz.net';
    		break;
            case 'pvz':
                relayURL += 'schuelervz.gadgets.apivz.net';
        	break;
	}
		
    	relayURL += '/gadgets/files/container/rpc_relay.html';
    	
    	var rpcToken = getURLParameter('rpctoken');
    	gadgets.rpc.setAuthToken('..', rpcToken);
    	
  	gadgets.rpc.setRelayUrl('..', relayURL);	
	    		
    	gadgets.rpc.call('..', "frameCallback", function(value) {
             alert('got callback with value: ' + value);
        }, "my callback parameters");	
}

    	
</script> 
</body>
</html>

In the code above the rpc target '..' indicates that the rpc call should be delivered to the parent frame. Since this parent frame is on another domain you register a relayURL which is on the same domain as the parent frame to handle this requests with the gadgets.rpc.setRelayUrl. The gadgets.rpc.setAuthToken method adds an additional auth token which is regenerated on every gadget rendering and is used to authenticate the sender. When you call gadgets.rpc.call the rpc library includes another iframe with the relay file and adds the designated method and parameters to this relay file. The relay file then calls the target method which has been specifically registered to be enabled for rpc calls by the gadgets.rpc.register method. Since relay url and target frame have the same domain this will not lead to any security errors which are catched by the browser.


  • Lesson 21: Interacting with an additional IFrame