Wkhtmltopdf不会使用子域打印图像

时间:2014-12-03 17:01:28

标签: symfony subdomain wkhtmltopdf

我使用 Wkhtmltopdf 将某些文件转换为 Symfony2 应用程序中的PDF格式。事实上,KnpSnappyBundle确实如此。这个捆绑很好,但我有一个奇怪的问题:

网络应用程序有两个子域:test.domainprod.domain。这两个子域目前具有完全相同的内容。 出于某种原因,使用prod子域时不会打印图像(转换为PDF)。但是,如果我直接访问URL,则图像存在。一个例子是:

<img src="prod.domain/img/theImage.jpg" /> <!-- This doesn't print the image but the URL is accessible -->
<img src="test.domain/img/theImage.jpg" /> <!-- This works right -->

我终于决定暂时使用test子域图片网址,但这很奇怪......有什么想法吗?

修改

我忘了说prod域使用SSL,而test没有。这似乎是主要问题。

我已从服务器执行:

 wkhtmltopdf https://prod.domain test.pdf

Loading pages (1/5)
QSslSocket: cannot resolve SSLv2_client_method               ] 10%
QSslSocket: cannot resolve SSLv2_server_method
Error: Failed loading page https://prod.domain (sometimes it will work just to ignore this error with --ignore-load-errors)

所以我再次尝试过:

wkhtmltopdf --ignore-load-errors https://prod.domain test.pdf

Loading pages (1/5)
QSslSocket: cannot resolve SSLv2_client_method               ] 10%
QSslSocket: cannot resolve SSLv2_server_method
Warning: Failed loading page https://prod.domain (ignored)  
Resolving links (2/5)
Counting pages (3/5)                                                      
Printing pages (5/5)                                                      
Done               

但新文件是银行。

如果我使用test域名(无SSL):

 wkhtmltopdf http://test.domain test.pdf

Loading pages (1/5)
QSslSocket: cannot resolve SSLv2_client_method               ] 21%
QSslSocket: cannot resolve SSLv2_server_method
Resolving links (2/5)                                              
Counting pages (3/5)                                                      
Printing pages (5/5)                                                      
Done                      

我收到前两个错误,但它有效,文件正确。

3 个答案:

答案 0 :(得分:3)

我有一次类似的问题。

你总是要记住wkhtmltopdf在服务器上运行。

这意味着:

  • 与您的开发机器不同的ip(对prod.domain的IP限制?)
  • 没有会话开始(只有登录用户才能看到该文件?)
  • 不知道您的主机文件(也许您已在主机文件中定义了prod.domain?)

在运行 wkhtmltopdf 的服务器上登录时,尝试 wget prod.domain/img/theImage.jpg

答案 1 :(得分:2)

在黑暗中拍摄...尝试通过动作代理图像。我们首先用Imagine加载文件,然后在Response中输出图像内容,这样的东西是这样的:

/**
 * @Route("/someroute/image", name="someroute_image")
 * @Method("get")
 */
public function imageAction(Request $request)
{
    $imagine = new Imagine();
    $absoluteUrl = $request->getSchemeAndHttpHost() . $this->get('templating.helper.assets')->getUrl('/images/logo.png');
    $image = $imagine->open($absoluteUrl);
    $response = new Response($image->get('png'));
    $response->headers->set('Content-Type', 'image/png');
    return $response;
}

链接到img标记的src=属性中的操作,而不是直接链接到图像。

答案 2 :(得分:1)

我认为我有同样的问题,继承我的代码(很老)

protected function prepareForRender($data) {

    $data['app']=array('request' => array('schemeAndHttpHost' => "http://your.host.com"));
    $this->container->enterScope('request');
    $this->container->set('request', new Request(), 'request');
    return $data;
}  

public function generatePdf(){

        $data=array();
        $data=$this->prepareForRender($data);

        $html=$this->container->get('templating')->render('someBundle:Report:foo.pdf.html.twig', $data);
        try {
            $pdfString=$this->knp_snappy->getOutputFromHtml($html, array(
                'enable-javascript' => true, 
                'javascript-delay' => 1000, 
                'no-stop-slow-scripts' => true, 
                'no-background' => false, 
                'lowquality' => false,
                'page-height' =>200,
                'page-width'  => 300,
                'encoding' => 'utf-8',
                'images' => true,
                'cookie' => array(),
                'dpi' => 300,
                'image-dpi' => 300,
                'enable-external-links' => true,
                'enable-internal-links' => true
            ));
        } catch(\Exception $e) {
            $this->logger->crit($e->getMessage());
        }

        return $pdfString;
}

和img src必须是一个绝对的网址,如:

<img width="405" height="130" src="{{ app.request.schemeAndHttpHost }}/bundles/akdjaskld/Header.png" alt="">

你最好从http://your.host.com中创建一个参数,这样你就可以为每个阶段创建不同的版本,也许你只是错过了images=>true选项