FCGI::Buffer - 验证、缓存和优化 FCGI 输出
版本0.19
FCGI::Buffer 通过HTML::Lint
传递来验证您生成的 HTML。
FCGI::Buffer 通过减少、过滤和压缩输出来加速传输以及几乎无缝地利用客户端和服务器缓存来优化 FCGI 程序。
要利用客户端缓存,也就是说,减少对服务器请求相同数据的不必要的调用:
use FCGI;
use FCGI::Buffer;
# ...
my $request = FCGI::Request();
while($request->FCGI::Accept() >= 0) {
my $buffer = FCGI::Buffer->new();
$buffer->init(
optimise_content => 1,
lint_content => 0,
);
# ...
}
为了还利用服务器缓存,也就是说,当不同的客户端请求您提供相同的数据时保存重新生成的输出,您将需要创建一个缓存。但这很简单:
use FCGI;
use CHI;
use FCGI::Buffer;
# ...
my $request = FCGI::Request();
while($request->FCGI::Accept() >= 0) {
my $buffer = FCGI::Buffer->new();
$buffer->init(
optimise_content => 1,
lint_content => 0,
cache => CHI->new(driver => 'File')
);
if($buffer->is_cached()) {
# Nothing has changed - use the version in the cache
$request->Finish();
next;
# ...
}
}
要暂时阻止使用服务器端缓存,例如在发布代码更改之前进行调试时,请将 NO_CACHE 环境变量设置为任何非零值。这也将阻止 ETag 添加到标头中。如果您在打印中遇到有关宽字符的错误,则意味着您忘记在非 ASCII 字符上发出纯 HTML。请参阅 HTML::实体。作为一种破解方法,您还可以使用 Text::Unidecode 删除重音等,它效果很好,但并不是您真正想要的。
创建一个 FCGI::Buffer 对象。对每个 FCGI::Accept 执行以下操作之一。
设置各种选项并覆盖默认值。
# Put this toward the top of your program before you do anything
# By default, generate_tag, generate_304 and compress_content are ON,
# optimise_content and lint_content are OFF. Set optimise_content to 2 to
# do aggressive JavaScript optimisations which may fail.
use FCGI::Buffer;
my $buffer = FCGI::Buffer->new()->init({
generate_etag => 1, # make good use of client's cache
generate_last_modified => 1, # more use of client's cache
compress_content => 1, # if gzip the output
optimise_content => 0, # optimise your program's HTML, CSS and JavaScript
cache => CHI->new(driver => 'File'), # cache requests
cache_key => 'string', # key for the cache
cache_age => '10 minutes', # how long to store responses in the cache
logger => $self->{logger},
lint_content => 0, # Pass through HTML::Lint
generate_304 => 1, # When appropriate, generate 304: Not modified
save_to => { directory => '/var/www/htdocs/save_to', ttl => 600, create_table => 1 },
info => CGI::Info->new(),
lingua => CGI::Lingua->new(),
});
如果没有给出cache_key,则会生成一个可能不唯一的cache_key。 cache_key 应该是一个唯一值,具体取决于浏览器设置的值。
缓存对象将是一个能够理解 get_object()、set()、remove() 和created_at() 消息的对象,例如 CHI 对象。它用作服务器端缓存,以减少重新运行数据库访问的需要。
默认情况下,项目会在服务器端缓存中保留 10 分钟。这可以通过请求中的cache_control HTTP 标头覆盖,并且可以通过init() 的cache_age 参数更改默认值。
Save_to 功能可将动态页面的输出存储到 htdocs 树中,并用静态链接替换指向该页面的未来链接,以避免通过 CGI。 Ttl 设置为静态页面被视为活动的秒数,默认为 10 分钟。如果设置为 0,页面将永远存在。要启用 save_to,还必须给出 info 和 lingua 参数。当还提供缓存时效果最佳。仅在保证输出与给定参数集相同的情况下使用(启用generate_304的标准相同)。您可以根据具体情况将其关闭,如下所示:
my $params = CGI::Info->new()->params();
if($params->{'send_private_email'}) {
$buffer->init('save_to' => undef);
}
Info 是一个可选参数,用于提供有关 FCGI 环境的信息,例如 CGI::Info 对象。
Logger 将是一个理解 debug() 的对象,例如 Log::Log4perl 对象。
要生成last_modified标头,您必须提供一个缓存对象。
Init 允许传递选项的引用。所以这两个方法都有效: use FCGI::Buffer; #...我的 $buffer = FCGI::Buffer->new(); $b->init(generate_etag => 1); $b->init({generate_etag => 1, info => CGI::Info->new() });
一般来说,通过引用传递更好,因为它向堆栈复制的内容较少。
如果您给 init() 一个缓存,然后再给cache => undef,则不再使用服务器端缓存。当您在创建 HTML 时发现错误情况并决定不再希望将输出存储在缓存中时,这非常有用。
init 的同义词,因历史原因而保留。
如果允许服务器在本地存储结果,则返回 true。这是返回标头中 X-Cache 的值。
如果输出已缓存,则返回 true。如果是,则意味着 FCGI 脚本中所有昂贵的例程都可以被绕过,因为我们已经将结果存储在缓存中。
# Put this toward the top of your program before you do anything
# Example key generation - use whatever you want as something
# unique for this call, so that subsequent calls with the same
# values match something in the cache
use CGI::Info;
use CGI::Lingua;
use FCGI::Buffer;
my $i = CGI::Info->new();
my $l = CGI::Lingua->new(supported => ['en']);
# To use server side caching you must give the cache argument, however
# the cache_key argument is optional - if you don't give one then one will
# be generated for you
my $buffer = FCGI::Buffer->new();
if($buffer->can_cache()) {
$buffer->init(
cache => CHI->new(driver => 'File'),
cache_key => $i->domain_name() . '/' . $i->script_name() . '/' . $i->as_string() . '/' . $l->language()
);
if($buffer->is_cached()) {
# Output will be retrieved from the cache and sent automatically
exit;
}
}
# Not in the cache, so now do our expensive computing to generate the
# results
print "Content-type: text/htmln";
# ...
奈杰尔·霍恩 (Nigel Horne),
即使在产生大量不同输出的脚本中,例如电子商务情况,FCGI::Buffer 也应该是安全的。然而,在这些页面上,我强烈建议将generate_304设置为0并发送HTTP标头“Cache-Control:no-cache”。
使用模板时,请确保不要使用它输出到 STDOUT,而是需要捕获到变量中并打印它。例如:
my $output;
$template->process($input, $vars, $output) || ($output = $template->error());
print $output;
如果您使用