iframe with RPC "installed"

by David Iglesias

HTML

<h1>
iframed but you can ask me things!
</h1>

<p>
  I'm under control by:
  <ul>
    <li id="handler">Nobody!</li>
  </ul>
</p>

<label>
  Secret value:<br />
  <input type="text" id="secret" placeholder="Type a secret value here!" />    
</label>

CSS

label {
  display: flex;
  flex-direction: column;
}
input {
  flex: 1;
  font-size: 16px;
  padding: 6px;
}

JavaScript

(function() {
  const handler = document.getElementById('handler');
  const secret = document.getElementById('secret');

	let handlerId;

	const sendResponse = (e, request, data) => {
    e.source.postMessage({
    	secretId: request.secretId,
      requestId: request.requestId,
      ...data,
    }, "*");
  }

	const handleMessage = (e) => {
    console.debug('Received message inside iframe...', e);
    
    const data = e.data;
    if (handlerId && data.type === "hi") {
      // Already authenticated, don't be too kind...
      sendResponse(e, data, {
        error: 'You only need to say hi once!',
      });
    } else if (handlerId && data.secretId === handlerId) {
      // Known event types...
      switch (data.type) {
        case 'secret': 
          sendResponse(e, data, {
            secret: secret.value,
          });
          break;
        default: 
          sendResponse(e, data, {
            error: `Don't know how to handle [${data.type}]`,
          });
      }
    } else if (!handlerId && data.type === "hi") {
      // Handshaking!
      handlerId = e.data.secretId;
      handler.innerHTML = 'iframe ' + handlerId;
      sendResponse(e, data, {
        type: 'ack-hi',
      });
    } else {
      sendResponse(e, data, {
        error: 'Ignoring message, be more polite!',
      });
    }
  }

	window.addEventListener('message', handleMessage);
}());