Print document from cross-origin iframe

When you need to show content from some other site, such as Google Docs, you can easily embed it inside an iframe. Google Docs even generates it for you. But what if you need to print that document via some button click? You can not do that, because the cross-origin policy does not allow it.

You have basically two options.

A) Create some proxy function on your server. But that is only available when you actually have a server and not just some hosted WordPress.

B) Create proxy iframe, which you are actually allowed to print, because there is no cross-origin involved. Then load the desired iframe inside the proxy iframe. Attach onload=”print()” on the target iframe, so the print starts automatically once it is loaded.

Working solution is below, have a nice day 🙂 Let me know, if it helped you.

Comments and suggestions for improvements are welcome. Hints: The iframe is not destroyed after print() is invoked, which might lead to memory leaks. Second issue is that you might need to calculate height of the iframe content, so that it is correctly printed. But if you can safely guess it, then you are fine.

  /**
   * Load iframe from cross-origin via proxy iframe
   * and then invokes the print dialog.
   * It is not possible to call window.print() on the target iframe directly
   * because of cross-origin policy.
   * 
   * Downside is that the iframe stays loaded. 
   */
  function printIframe(url) {
    var proxyIframe = document.createElement('iframe');
    var body = document.getElementsByTagName('body')[0];
    body.appendChild(proxyIframe);
    proxyIframe.style.width = '100%';
    proxyIframe.style.height = '100%';
    proxyIframe.style.display = 'none';

    var contentWindow = proxyIframe.contentWindow;
    contentWindow.document.open();
    // Set dimensions according to your needs.
    // You may need to calculate the dynamically after the content has loaded
    contentWindow.document.write('<iframe src="' + url + '" onload="print();" width="1000" height="1800" frameborder="0" marginheight="0" marginwidth="0">');
    contentWindow.document.close();
  }