1

我和我的同事正在维护和开发一个通过mod_perl.

现在我们正在经历一次重大的遗留代码重构,其中我们已经实现了某种 MVC 模式。

除其他外,我的任务是确保所有 HTTP 响应标头都被处理并发送回主控制器内的浏览器。例如,如果需要重定向,页面处理程序会抛出异常,然后主控制器捕获它并生成相应的标头。

在我开始实现 cookie 处理之前,一切看起来都很好。在此之前,我们的代码只是在需要时打印 cookie 标头以输出,如下所示:

# $response is an instance of the CGI class
print $response->redirect(
    -uri => "/some_uri/",
    -cookie => $response->cookie(
         -name => 'user_id',
         -value => $user->{'id'},
         -path => '/', -expires => '+1M'));

现在我希望$response对象存储该信息,以便以后可以将所有标头一起发送。我认为它会是这样的:

sub page_handler {
    # ...
    $response->cookie(-name => 'user_id',
         -value => $user->{'id'},
         -path => '/', -expires => '+1M');
    return;
}

# And then, inside the controller

sub controller {
    # ...
    # the same $response instance 
    print $response->header();
    print $output;
    # ....
    exit();
}

但似乎CGI类对象并没有存储它使用该header方法创建的所有标头。一些标题似乎持续存在,而另一些则没有,这是我得到的re.pl

$ use CGI;        
$ my $response = CGI->new();
$CGI1 = CGI=HASH(0xa6efba0);
$ $response->header();
Content-Type: text/html; charset=ISO-8859-1

$ $response->header(-type => 'text/plain', -charset => 'UTF-8', -status => '200 OK');
Status: 200 OK
Content-Type: text/plain; charset=UTF-8

$ $response->header();
Content-Type: text/html; charset=UTF-8 

我希望最后一个输出与前一个输出相同,或者与第一个输出相同,但我尚未设置任何标题。我没想到它会部分改变。

这就是为什么我要问我的问题:为什么 CGI.pm 对象中的某些标头信息会持续存在,而另一些则不会?

我是否错误地使用了该对象?有没有办法按照我的意图使用它?

PS:很抱歉这个问题很长,我想确保你明白我想要做什么。

PPS:另外,我知道这里的很多人建议不要使用 CGI 并使用 Catalyst。恐怕现在不是一个选择,因为我们有太多遗留代码,我们希望完全摆脱 mod_perl。这仅对特定功能是必需的。

4

1 回答 1

0

要回答您的问题,标头方法不存储任何信息,没有什么是持久的。

随着您的标题“对象”示例持续存在,阅读 TFM有助于:

-charset 参数可用于控制发送到浏览器的字符集。如果未提供,则默认为 ISO-8859-1。作为副作用,这也设置了 charset() 方法。[强调我的]

在使用一些参数调用 header 之后,将其调用为默认值,唯一要“保留”的是字符集。

对于您的 cookie 问题,我认为您必须存储 $response->cookie(); 某处。TFM并没有说 cookie() 子将数据存储在任何地方,它只是说它创建了一个 cookie。

不过,我同意 Sinan 的观点——抛出异常是疯狂的说法,尤其是涉及 CGI.pm 的重定向子。我会重新考虑那个。或者完全相反,只使用异常处理来编写整个 web 应用程序——一路上会有一些很好的笑声:o)

于 2011-03-18T02:03:08.087 回答