5

我正站在一个充满解决问题的潜在方法的十字路口前。我的问题是我想将特定用户推荐给为他们呈现相关 PDF 文件的独特页面。最好,我想将它们引至一个站点,该站点没有相关的 MySQL 数据和用于 pdf 渲染的插件。希望您能阐明我应该使用哪种解决方案。

参考

  • 站点 A - 我更愿意推荐他们访问的站点
  • 站点 B - 包含 MySQL 数据和 PDF 插件的站点

信息

  • 这两个站点都是通过 CakePHP 1.3 构建的
  • 站点 A 目前没有附加数据库。它仅在对站点 B 的 API 调用上运行。
  • 这些 PDF 生成起来不会那么重,尽管找到一个解决方案也能解决这个问题会很有趣
  • 对这些 PDF 的引用发生在事件中,并且不会同时发送给成千上万的用户。

解决方案#1

将他们推荐给站点 B 并在那里生成所有内容。

优点:易于修复。
缺点:我不希望这些用户知道站点 B。站点 B 主要用于内部通信,最好让给定的用户离开这个站点。
想法:宁可避免这个。

解决方案#2

在站点 A 上有一个页面,它卷曲一个等于解决方案 #1 的页面,然后输出相同的结果。

优点:几乎一样容易修复。
缺点:想不出来。
思考:浏览器会理解我输出的是 PDF 吗?或者我是否(如果可能)从 cURL 请求中复制标题回复并header()在输出之前将它们设置为自己的?

解决方案#3

在站点 B 中生成一次 PDF 并将其放置在站点 A 上。然后只需参考 .pdf 链接。

优点:加载速度更快。在这种情况下,这并不重要,甚至可能被忽视。
缺点:不能轻易修改 PDF 输出。
思考:我将如何传输文件?这两个站点位于同一台服务器上,因此只需更改路径即可,但是站点之间的所有其他通信都不需要共享服务器。破坏这种设计真是太可惜了。也许我必须进行高级 cURL 请求并将 pdf 文件作为 POST 从站点 B 发送到站点 A 并上传?不过,这似乎也不是很好的解决方案。

解决方案#4

从站点 A 到站点 B 运行 API,以根据来自 url 的 ID 获取相关数据。但也有站点 A 上的 PDF 插件。

优点:从某种意义上说,这是一种非常合乎逻辑的方法。
缺点:我宁愿只在站点 B 上生成所有 PDF。使管理所有这些变得更容易。
思考:我有点不确定这种方法与解决方案 2 相比有多少(如果有的话)更有益。

非常感谢您的时间。请激励给定的解决方案之一,或提出您自己的解决方案。

编辑:虽然代码示例总是受到赞赏,但我更感兴趣的是为什么应该使用哪种解决方案或另一种解决方案的共鸣和逻辑。我已经知道如何通过编码解决大多数这些解决方案。对于访问者,请随时链接到有关您的回复的相关功能和方法。

4

3 回答 3

1

看起来您想从公众视线中隐藏站点 B。

最简单的方法是在站点 A 和站点 B 之间创建反向代理。您可以执行类似 sitea.com/pdf-items/ 之类的操作,将服务于 siteb.com/

编辑:

反向代理可以是跨域的,服务器不必共享任何共同的东西,除了站点 A 可以访问站点 B(听起来已经是这样了)

Apache 有一个使用 mod_proxy 的简单方法(http://httpd.apache.org/docs/2.2/mod/mod_proxy.html

一个快速的谷歌提取了一个在 Apache 上设置它的指南。http://www.apachetutor.org/admin/reverseproxy

Nginx 也有一个 http://www.cyberciti.biz/tips/using-nginx-as-reverse-proxy.html

IIS 有点复杂,我从来没有设置过,但根据文档,这种能力确实存在。

编辑2:接近

在这里我们不必担心 PHP 组件。发生的情况是,Apache 服务器将根据指定的代理映射转发请求,例如,如果设置了代理 Sitea.com/pdf siteb.com/,那么 sitea.com/pdf/alpha.pdf 将实际请求 siteb.com/alpha。 .pdf 在此模式中,它将忽略 sitea.com PHP 路由,但将尊重 siteb.com 路由,因为它是一个完整的请求,但由 sitea 的网络服务器完成。

关于兑现,对siteb的请求,这意味着sitea.com/pdf/getpdf.php?id=1实际上会像访问sitea.com/getpdf.php?id=1一样经历所有动作。

或者,如果您想在 siteA.com 上设置 VHOST,例如 pdf.sitea.com,您可以设置 pdf.sitea.com 映射到 siteb.com 的代理,但如果 sitea 和 siteb 都可公开访问,这将毫无用处。

如果您的受众可以使用 sitea.com 并且 siteB 位于访问受限的防火墙后面,则反向代理的效果最好,因此代理将允许 sitea.com 访问 siteb.com 的一部分,否则该部分将无法访问。

通过启用 proxy_mod 并在 VHOST 或服务器配置下设置 ProxyPass 和 ProxyReversePass,将修改的文件是主机的 siteA.com Apache 配置。

于 2012-11-28T15:39:30.080 回答
0

您始终可以在站点 B 上创建一个“隐藏”或至少未知的页面,该页面生成 PDF 并直接输出(没有下载对话框)。然后在站点 A 上,您可以直接插入到站点 B 的链接以从站点 B 下载内容,并将其显示给用户。

用户不会知道站点 B 存在,但它会变慢,因为两个服务器之间的数据流量更多。

在站点 B hiddenfile.php 上:

<?
$p = new PDFlib();
if ($p->begin_document("", "") == 0) {
    die("Error: " . $p->get_errmsg());
}
$p->set_info("Creator", "Hugo Delsing");
$p->set_info("Author", "Hugo Delsing");
$p->set_info("Title", 'Hi');

$p->begin_page_ext($docWidth, $docHeight, "");

$p->end_page_ext("");
$p->end_document("");

$buf = $p->get_buffer();

$len = strlen($buf);
header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=hello.pdf");
print $buf;
exit;
?>

并在现场 A downloadFile.php

<?
$content = implode('', file('siteb/hiddenfile.php?user=1'));
$len = strlen($content );
header('Content-type: application/pdf');
header("Content-Length: $len");
header('Content-Disposition: attachment; filename="downloaded.pdf"');
print $content;
exit;
?>

所以我想我会以不同的方式使用解决方案 B,以保留单独的服务器选项。为什么?所有解决方案都很好,但这曾经对您没有任何不利之处。所以我猜你回答了你自己的问题。

于 2012-11-28T13:34:28.790 回答
0

有趣的问题。从所有不同的解决方案中,我假设您在可以做的事情上非常灵活。

就我个人而言,我会将站点 B 用作带有数据库的作业队列服务器(尽管数据库在不同的服务器上也会更好)。询问用户的电子邮件地址,一旦工作(处理 PDF)完成,他们就会通过电子邮件将其通过电子邮件发送给他们,或者您可以按照我在评论中的建议将他们发送到一个页面,上面写着“生成 pdf,将在 10 内刷新秒”,它会不断刷新,直到找到生成的 PDF。这也将允许它很好地扩展(只需添加更多工作人员)并且不会在生成 PDF 时阻止用户。

您可以使用 Gearman 与 PHP 交互来创建作业队列。

http://php.net/manual/en/book.gearman.php

优点

  • 扩展性很好 - 如果您需要一次生成更多 PDF,只需添加更多工作人员
  • 使用不会在生成 PDF 时认为页面崩溃
  • 不仅限于 PDF,您可以在其中排队任何 CPU 密集型作业
  • 随着网站流量的增加,不需要被淘汰并用不同的东西替换(只需添加更多的工作人员)
  • 允许控制尝试生成 PDF 的进程/线程的数量(例如,apache 将允许一次生成 10 个或更多 PDF - 当直接在 Web 请求过程中完成时,您几乎无法控制它,这将是一种方式攻击者使您的网站崩溃)

缺点

  • 需要安装和设置 gearman
  • 需要您创建 gearman PHP 脚本才能实际生成 PDF

我走这条路的主要原因是用户体验、易于扩展和对工作进程的控制。

边注

尽管我确定您有自己的理由,但您对站点 A 和 B 的设置似乎有点奇怪。如果您有两台服务器,最好使用站点 A 上的 nginx 将所有请求代理到内部服务器 B,并在其上安装 Apache、DB 和 gearman。然后,随着站点流量的增长,您可以将应用程序分开以分开服务器。

于 2012-11-28T13:46:01.080 回答