通过iframe打印pdf(跨域)

时间:2016-07-02 20:49:32

标签: javascript

我需要打印PDF ...但是我收到错误

有解决方法吗?我只需要点击一下即可打印PDF文件

错误:

<?php

if(isset($_POST['createcomment'])){
    echo($_POST['sql']);    
}



    echo("  
                <form action='' method='post'>  
                    <textarea name ='comment' rows='4' cols = '50' value =''></textarea>
                        <button type='createcomment' name='createcomment' value='createcomment'>
                            Comment
                            <input type = 'hidden' name = 'sql' value ='SELECT * FROM `create_event` WHERE `eventStatus` = 'Happening' and 'approved' = 'Approved' '</>
                        </button>
                </form>
        "); 


 ?>

的代码:

Uncaught SecurityError: Blocked a frame with origin "https://secure.domain.com" from accessing a frame with origin "https://cdn.domain.com". Protocols, domains, and ports must match.

6 个答案:

答案 0 :(得分:5)

您正在处理的错误与跨域保护和同源策略有关。

在您的情况下,如果您将此iframe嵌套在我们可以调用代理iframe的另一个本地iframe中,则可以打印跨域iframe。

由于代理iframe是本地的且具有相同的来源,因此您可以毫无问题地打印它,并且还会打印跨域iframe。

见下面的例子:

index.html(容器)

$(function() {
  var url = 'proxy.html'; // We're not loading the PDF but a proxy which will load the PDF in another iframe.

  var iframe = $('<iframe src="' + url + '"></iframe>').appendTo($('#main'));

  iframe.on('load', function(){
    iframe.get(0).contentWindow.print();
  });
});

proxy.html(代理)

<body>
  <iframe src="http://ANOTHER_DOMAIN/PDF_NAME.pdf"></iframe>
</body>

使用此解决方案,您不再遇到跨域问题,您可以使用print()函数。您需要处理的唯一事情是将PDF URL从容器传递到代理,以及检测何时实际加载带有PDF的iframe的方法,但这取决于您正在使用的解决方案/语言。 / p>

答案 1 :(得分:2)

有一种解决方法。

  1. 在服务器中创建一个端点,以返回外部网址的HTML内容。 (因为您无法从浏览器获取外部内容 - 同源政策

  2. 使用$.get从您的网址抓取外部内容并将其附加到iframe

  3. 类似的东西:

    <强> HTML:

    <div id="main">
        <iframe id="my-iframe" style="display:none"></iframe>
    </div>
    

    <强> JS:

    $.get('https://secure.domain.com/get-cdndomaincom-url-content', function(response) {
        var iframe = $('#my-iframe')[0],
            iframedoc = iframe.contentDocument || iframe.contentWindow.document;
    
        iframedoc.body.innerHTML = response;
        iframe.contentWindow.print();
    });
    

    get-cdndomaincom-url-content的C#实施:

    Easiest way to read from a URL into a string in .NET

答案 2 :(得分:1)

- 问题 -

HiDeo是对的,这是一个跨域问题。它是CORS的一部分,对于网络的安全性来说是一件好事,但也是一种痛苦。

- 哲学 -

有很多方法可以解决CORS问题,但我相信找到适合所有情况并且继续使用它的解决方案。这样可以创建更简单的代码来推理并保持代码一致,而不是更改和创建边缘情况的代码。这可以创建一个更难的初始解决方案,但是无论用例如何都可以重复使用该方法,最终节省时间。

- 应答 -

我们的团队处理跨域请求问题的方式完全绕过了它。 CORS仅适用于浏览器。因此,解决此问题的所有案例的最佳方法是不向浏览器提供合理性。我们让服务器获取文档并将其提供给同一域中的浏览器。

(我是一个角色的家伙) 客户会说

之类的东西
$http.get('/pdf/x').then(function(){
    //do whatever you want with any cross-domain doument
});

服务器将具有您在此处看到的内容HTTP GET Request in Node.js Express

答案 3 :(得分:1)

这是一个CORS问题。有一个库充当CORS替代品,你可以在Xdomain CORS alternative Github找到它。它可以无缝地绕过CORS请求,有效地呈现跨域资源。

它有一个Javascript,AngularJS,以及一个JQuery包装器。我认为这将为您提供更优雅的解决方案,并且易于集成。试一试。

答案 4 :(得分:1)

您不需要代理服务器来解决此问题。您可以创建代理iframe,然后在代理iframe中动态创建另一个iframe。然后将onload =“print()”附加到它。

像这样的东西

  /**
   * 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();
  }

答案 5 :(得分:1)

我需要打印 PDF embedded through a data:application/pdf;base64,… iframe,但遇到了同样的跨域问题。

解决方案是convert the Base64 contents that I had into a blob,然后use put blob's object URL into the iframe src。这样做之后,我就可以打印该 iframe。

我知道不鼓励仅提供链接的答案,但将别人的答案复制到我自己的答案中也感觉不对。