Providing services to guest code

Having learned how to embed guest code and protect yourself from attacks, your next step is to learn how to provide services to the code such that it can interact with your host page.

Create guest code

Assume your third-party guest code is as follows (also available here):

<html>
  <head></head>
  <body>
    <input type="button" id="theButton" value="Say hello">
    <script type="text/javascript">
      document.getElementById('theButton').onclick = function() {
        sayHello();
      };     
    </script>
  </body>
</html>

When directly displayed, this file should look like:

The code you have created refers to the function sayHello. This is a function that your guest code will expect the container to provide; it represents a very simple contract whereby the guest code may ask its host page to perform services.

Create host page

Now create your host page as before like this:

<html>
  <head>
    <title>Caja host page</title>
    <script type="text/javascript"
            src="//caja.appspot.com/caja.js">
    </script>
  </head>

  <body>
    <h1>Caja host page</h1>
    <div id="guest"></div>
    <script type="text/javascript">
      caja.initialize({
        cajaServer: 'https://caja.appspot.com/',
        debug: true
      });
      caja.load(document.getElementById('guest'), undefined, function(frame) {
        frame.code('https://developers.google.com/caja/demos/providingservices/guest.html',
                   'text/html')
             .run();
     });
    </script>
  </body>
</html>

Pressing the Say hello button does nothing at this point, since we have yet to provide the guest code with that function.

Provide tame services

Now add to the host page the following:

<html>
  <head>
    <title>Caja host page</title>
    <script type="text/javascript"
            src="//caja.appspot.com/caja.js">
    </script>
  </head>

  <body>
    <h1>Caja host page</h1>
    <div id="guest"></div>
    <script type="text/javascript">
      function alertGreeting() { alert('Hello world'); };
      caja.initialize({
        cajaServer: 'https://caja.appspot.com/',
        debug: true
      });
      caja.load(document.getElementById('guest'), undefined, function(frame) {
        caja.markFunction(alertGreeting);
        var tamedAlertGreeting = caja.tame(alertGreeting);
        frame.code('https://developers.google.com/caja/demos/providingservices/guest.html',
                   'text/html')
             .api({ sayHello: tamedAlertGreeting })
             .run();
     });
    </script>
  </body>
</html>

The complete host page is available here. The new code uses the caja object to tame the function alertGreeting. This is done by first telling Caja to allow guest code to call it as a function, via markFunction, then returning a tamed version of the function by calling tame. It then supplies this function as an API to the guest code, via the api() function of the frame, under the name sayHello.

Loading the host page and pressing the button should give you a result like this:

Run it yourself

Review

  • You created an API so that guest content can invoke services from your host page; and
  • The guest content was able to invoke the services by calling a function with an agreed-upon name.

Next steps