我正在努力实现
给出顶级网址,例如http://www.myapp.com/
如果有人要求:
http://www.myapp.com/questions/id/1
我想获取“questions / id / 1”部分并将其传递给相应的Perl脚本以检索所需的资源。
我取得的成就
目前我知道如果网址中有一个额外的级别,如何这样做:
http://www.myapp.com/model/questions/id/1
其中“model”只是一个典型的Perl CGI脚本,除了它没有“.pl”扩展名,并且Apache perl处理程序配置为处理这个并且“questions / id / 1”部分被解释为路径info(通过CGI-> path_info())传递给“model”。
我从Andrew Hanenkamp在onlamp.com上关于这个主题的文章中提出这个想法: Developing RESTful Web Services in Perl
什么仍然错误
然而,这种方法不适用于顶级网址,因为没有地方放置“模型”或任何处理程序被调用。我尝试在配置中设置默认文档设置,以便http://www.myapp.com/默认为http://www.myapp.com/modle。
因此,键入http://www.myapp.com/questions/id/1的处理方式为http://www.myapp.com/model/questions/id/1
但是,Apache认为这是404错误。
我怎样才能做到这一点?这甚至是Perl的工作还是更好地在Apache配置级别处理,或者可能利用一些Apache API来捕获404错误并从那里提取“/ questions / id / 1”部分?我不知道。也许有人在这里知道。 ; - )
注意: 对于提出这个问题的长期措辞和迂回方式道歉。我不太确定引出主题答案所需的术语是什么。提到一个以R开头并以T结尾的四个字母的单词,同时在此处和其他地方提出这个问题,引起了关于所述字母单词的性质的热烈讨论,以及对使用某种框架或其他框架的无益建议。我只是想知道这些框架如何实现这个功能,我想在Perl中实现一个,以学习如何实现它。
更新 其中一个建议的答案让我尝试了mod_rewrite。作品。但是,为每个映射手动设置Apache的conf是相当不切实际的。进一步搜索让我看到O'Reilly的书“Practical mod_perl”。在其中,Bekman和Cholet写了关于通过Apache CPAN包以编程方式访问mod_rewrite来设置重写。 Appendix 10 : "mod_rewrite in Perl"现在编写一些代码来测试本书的想法。与此同时,如果有更好的方法可以实现这一目标,请分享。
结论
在两个uri路由/调度程序(或Whatchamacallit)脚本进行原型设计之后,一个依靠mod_rewrite来调用它,另一个依赖于ErrorDocument;我得出结论,mod_rewrite是实现它的正确方法。
ErrorDocument方法错误,因为它不会保留重定向页面的POST数据。 由于POST数据不可用于ErrorDocument调用的自定义错误处理程序脚本,因此无法向http://www.myapp.com/questions发送POST请求以创建新资源。此外,由于定义中的每个请求都不会访问物理文件,因此Apache的错误日志将充满spurios 404文件未找到的错误。这可能是一个很大的问题,即服务器的事务量很高。感谢大家指点我正确的方向。现在我的好奇心已经满足了。
答案 0 :(得分:1)
您可以在.htaccess
文件或Apache配置文件中定义重写规则。
有关详细信息,请参阅mod_rewrite。
在您的情况下,.htaccess
文件可能如下所示:
AddHandler cgi-script .cgi
Options +ExecCGI
RewriteEngine on
RewriteRule ^(questions/id/.*)$ model.cgi/$1 [L]
如果您只需要处理/question/id/
个请求,这应该可以使用。但您可能希望通过Perl应用程序处理所有请求。所以实际上将所有请求传递给您的应用程序可能是个好主意类似的东西:
RewriteRule ^(.*)$ app.cgi/$1 [L]
让你的应用程序发送请求比。 除了...总有一些例外。您需要让Apache为您提供静态文件。而且您需要Apache不要将您的应用程序文件(可执行文件和配置文件)作为静态文件提供。因此,大多数现代Perl框架都将静态存储在单独的目录中,例如“public”。因此,您将所有图像,css,js等放入/ public并按以下方式配置Apache:
RewriteCond %{DOCUMENT_ROOT}/public/%{REQUEST_URI} -f
RewriteRule ^(.*) public/$1 [L]
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} !-f
RewriteRule ^(.*) myapp.cgi [L]
此示例取自Mojolicious documentation。
如果用户请求'public'中存在的内容,Apache会向用户发送静态文件,并将所有其他请求重定向到您的应用。
在您的应用中,您需要向某些操作发送一些请求。实际上,你需要一个可以为你完成这项工作的模块。由Viacheslav Tykhanovskyi撰写的Routes::Tiny(也可在CPAN上提供)是一个不错的选择。
毕竟,如果你想知道框架是如何工作的,你为什么不潜入其中一个? Mojolicious和Dancer太大了,但是你可能会看到更小的东西,比如Lamework更适合现在成为标准的PSGI协议。
答案 1 :(得分:1)
我强烈建议使用Web开发框架。这将需要一些学习,但是,当你完成时,你会意识到你目前的方法远非理想。有许多简单的框架可以让您快速启动和运行。我建议使用Dancer(www.perldancer.org)。在Dancer中,设置路线就像下面的示例一样简单。
获取'/'=> sub {'Hello world!' }
另外,您不太可能想要使用CGI。 CGI通常具有非常差的性能并且基本上不存在。我建议您研究一下FastCGI和PSGI,它们都可以在Apache中使用。
答案 2 :(得分:1)
您可以捕获404错误并使用cgi脚本处理它。在您的顶级.htaccess文件(docroot / .htaccess)中:
ErrorDocument 404 /cgi/my-script.sh
然后在处理程序脚本(my-script.sh)中,原始路径将作为enviromnent变量REDIRECT_URL
传递。但请确保您的处理程序脚本通过添加Status: 200 OK
标头正确设置HTTP状态。这是一个示例cgi脚本(/cgi/my-script.sh):
#!/bin/sh
echo Status: 200 OK
echo Content-type: text/plain
echo
echo Your url was $REDIRECT_URL
(我不建议使用bourne shell编写cgi脚本,但它说明了该方法。)
您也可以将ErrorDocument设置放在httpd.conf文件中,但是任何更改都需要重启服务器;将它放入.htaccess可以更容易地在运行时进行调整。
关于自定义错误处理的Apache参考:http://httpd.apache.org/docs/2.1/custom-error.html
如果你正在使用mod_perl,那么将它设置为perl处理程序会更容易,更清晰(更不用说性能更好了);再次在顶级.htaccess文件(或httpd.conf)中:
SetHandler perl-script
PerlHandler MyThing::HandlerPackage
其中MyThing::HandlerPackage
是定义适当的handler
sub。