简体   繁体   English

在Perl CGI中正确编程/从不同的perl cgi文件访问相同的数据

[英]Correctly Programming in Perl CGI / Accessing the same data from differ perl cgi files

I am new to Perl CGI programming and have a few questions. 我是Perl CGI编程的新手,并且有几个问题。 Currently I have 1 HTML page and a bunch of perl pages. 目前,我有1个HTML页面和一堆perl页面。 The users starts on an HTML page where they enter their name and address. 用户从HTML页面开始,然后在其中输入其名称和地址。 This form then calls a Perl CGI file. 然后,此表单将调用Perl CGI文件。 Now when this Perl file executes it generates some HTML that the user will see as another page. 现在,当执行此Perl文件时,它将生成一些HTML,用户将其视为另一个页面。 Now inside the HTML that was generated by the perl file there is another form that calls another CGI script. 现在,在由perl文件生成的HTML内,还有另一种形式可以调用另一个CGI脚本。 This continues so that I basically have a Perl CGI file for every page. 继续进行,这样我基本上每个页面都有一个Perl CGI文件。

Is this the correct way to do things with CGI? 这是用CGI处理事情的正确方法吗?

The problem I am having with this is that I don't know how to share information around all these perl files as they only communicate with each other through the actions of forms. 我遇到的问题是,我不知道如何在所有这些perl文件之间共享信息,因为它们仅通过表单操作相互通信。

I have a small shopping cart and therefore need to be able to initialize, get and set the contents of it from multiple pages. 我的购物车很小,因此需要能够从多个页面进行初始化,获取和设置其内容。

How can I share data between the files as I described above? 如上所述,如何在文件之间共享数据?

To re-iterate what Sinan said, the shopping cart needs to be done using sessions. 要重申思南所说的话,购物车需要使用会话来完成。

I will try to explain a bit more about how it all works, since your question seems to imply you would like to understand the details. 由于您的问题似乎暗示您希望了解详细信息,因此我将尝试进一步解释其工作原理。


There are two concepts that are involved: A Session Cookie, and a Session database on the server side. 涉及两个概念:会话Cookie和服务器端的会话数据库。

Your web server has an internal "sessions" database - which is basically a mapping between a long string known as the "Session Key" and a blob of data. 您的Web服务器有一个内部“会话”数据库-基本上是一个长字符串(称为“会话密钥”)和数据块之间的映射。 This database can be built into the web server, or in case of Perl CGI, be implemented by a special Perl module. 该数据库可以内置到Web服务器中,或者在Perl CGI的情况下,可以通过特殊的Perl模块实现。

What gets stored in this blob of data in a Session database? 会话数据库中的此数据块中存储了什么? Anything your CGI script decides to store - in your case, the current state of the shopping cart. 您的CGI脚本决定存储的所有内容-在您的情况下,就是购物车的当前状态。

How does the information get shared between the pages? 页面之间如何共享信息? A special " Session Cookie " is generated by your session module, with the value of the cookie being the same "Session Key" used to store the blob of data on the server in session database. 您的会话模块会生成一个特殊的“ 会话Cookie ”,该Cookie的值与用于在会话数据库中的服务器上存储数据块的“会话密钥”相同。 It is then stored by the user's browser like all the other cookies, except its value is only valid "for the duration of a session" - it expires after a short period of time or if you close your browser. 然后,它像其他所有cookie一样,由用户的浏览器存储,除了它的值仅在“会话持续时间内”有效-它会在很短的时间后或在您关闭浏览器后失效。 Then, when the user continues with the web app, the cookie value gets sent back to the server and therefore your CGI script knows to re-use that session key. 然后,当用户继续使用Web应用程序时,cookie值将发送回服务器,因此您的CGI脚本知道重新使用该会话密钥。

NOTE : An alternate approach (instead of using a cookie) is to pass the session ID value between all your requests (eg code it into all GET URLs and POST forms). 注意 :一种替代方法(而不是使用cookie)是在所有请求之间传递会话ID值(例如,将其编码到所有GET URL和POST表单中)。


As far as Perl CGI implementation, it depends on the specific Perl web framework you use - the basic session work can be done using CGI::Session CPAN module (there is a good tutorial for it as well ). 至于Perl CGI的实现,它取决于您使用的特定Perl Web框架-基本的会话工作可以使用CGI::Session CPAN模块来完成(也有不错的教程 )。 Another frequent option for those using Apache web server is Apache::Session . 对于使用Apache Web服务器的用户来说,另一个常见的选择是Apache::Session

What a general Session related module does is provide you with the APIs to: 常规会话相关模块的作用是为您提供以下API:

  • Manage Session database 管理会话数据库
  • Store/retrieve data in Session database using Session key (aka Session ID) 使用会话密钥(即会话ID)在会话数据库中存储/检索数据
  • Obtain the user's current session ID (from the session cookie value), if any 获取用户的当前会话ID(从会话cookie值)(如果有)
  • Generate a new session ID for the user, if needed 如果需要,为用户生成一个新的会话ID
  • Send the session ID value as a cookie to be stored in HTTP response to user's browser. 将会话ID值作为cookie发送给用户的浏览器,以存储在HTTP响应中。

Any decent Perl web framework has session capabilities built in (they are still implemented using some sort of Session management Perl module, but the framework provides easy-to-use APIs. 任何体面的Perl Web框架都内置有会话功能(它们仍使用某种会话管理Perl模块来实现,但是该框架提供了易于使用的API。

As an example of "easy to use", in Embperl, to store a value in a session, all you do is $udat{shopping_cart} = \\%shopping_cart_data and to retrieve it you do %shopping_cart_data = %$udat{shopping_cart} - %udat being a special hash name). 作为“易于使用”的示例,在Embperl中,为了在会话中存储值,您要做的就是$udat{shopping_cart} = \\%shopping_cart_data并要检索它,您可以执行%shopping_cart_data = %$udat{shopping_cart} - %udat是一个特殊的哈希名称)。 That's it. 而已。 All the details hidden from you by the framework. 框架对您隐藏的所有细节。


UPDATE: 更新:

This has pretty much nothing to do with what seems to me the actual question being asked, but it's nevertheless a valid point that a comment to this answer made me think of. 在我看来,这与实际提出的问题几乎没有任何关系,但是,对这个答案的评论让我想到的却是一个有效的观点。

In the interest of improving the overall quality of your code, you should always abstract away as much of the general business logic. 为了提高代码的整体质量,您应该始终抽象出尽可能多的常规业务逻辑。 In this case, if you have any generic logic for working with the shopping cart data which is shared between your different Perl CGI scripts, that logic should be abstracted away into a separate Perl module. 在这种情况下,如果您有用于处理在不同Perl CGI脚本之间共享的购物车数据的任何通用逻辑,则应将该逻辑抽象为单独的Perl模块。

In addition, as further improvements: 另外,作为进一步的改进:

  • You should consider MVC (model-view-controller) design for any complicated web app. 您应该为任何复杂的Web应用程序考虑MVC(模型视图控制器)设计。 To make this easier, pick an MVC-compliant Perl web framework (I think Catalyst is considered the main option these days but do your own research before setting on one. 为了简化这一过程,请选择一个符合MVC的Perl Web框架(我认为Catalyst如今已被视为主要选择,但是在进行设置之前,请先进行自己的研究。

  • You should also have a design that allows you to modularize and re-use web (view) elements - eg the top var of the application that probably will display # of items in the shopping cart would always be pretty much the same HTML, and you should not duplicate that HTML across different views. 您还应该设计一个允许您模块化和重用Web(视图)元素的设计-例如,应用程序的顶部var可能会显示购物车中的商品数,它们总是与HTML几乎相同。不应在不同的视图之间复制该HTML。 (if you aren't sure what I'm talking about, look at top 2 lines on Amazon's web page). (如果您不确定我在说什么,请查看亚马逊网页上的前2行)。 There are different techniques for achieving that, which go well beyond the scope of your question (frames, web frameworks with merged views, Perl module for View printing, etc...). 有多种方法可以解决此问题,这些技术远远超出了您的问题范围(框架,带有合并视图的Web框架,用于视图打印的Perl模块等)。

The short answer is: You are doing it all wrong. 简短的答案是:您做错了所有事情。

You need to store the contents of the shopping cart for each visitor on the server side using server side sessions. 您需要使用服务器端会话在服务器端为每个访问者存储购物车中的内容。

See, for example, My Experiences with using CGI::Application and Template::Toolkit To Build an Online Shopping Cart by Justin Simoni . 例如,请参阅Justin Simoni的“ 我使用CGI :: Application和Template :: Toolkit构建在线购物车的经验”。

If you try to store the contents of the shopping cart in HTML pages you serve, malicious visitors can easily change, say, prices and give themselves nice discounts as people discovered in the mid nineties. 如果您尝试将购物车中的内容存储在所服务的HTML页面中,那么恶意访问者可以轻松地更改价格(例如价格),并像90年代中期人们发现的那样给他们自己很大的折扣。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM