首页 > 学技术 > 技术网文 > Perl > 正文

[原创] Perl CGI Session,要求加精


来源 chinaunix.net kuqin整理

最近看到很多帖子都是关于Perl CGI Session的使用的,在此算是统一回复罢

正确的代码如下(1.pl)

#!/usr/bin/perl
use CGI;
use CGI::Session;

my $cgi= new CGI;
my $session = new CGI::Session("driver:File", $cgi , {Directory=>;'/tmp'});
my $cookie = $cgi->;cookie(CGISESSID =>; $session->;id );
print $cgi->;header(-cookie=>;$cookie);
$session->;param('f_name', 'Sherzod');
print "<script language='javascript'>;";
print " location.href='2.pl';";
print "</script>;";


(2.pl)

#!/usr/bin/perl -w
use strict;
use CGI;
use CGI::Session;

my $cgi = new CGI;
my $session = new CGI::Session("driver:File", $cgi ,{Directory=>;'/tmp'});
my $strName = $session->;param("f_name");
print $cgi->;header(); 
print "-------------------$strName--------------------\n"; 


前面的帖子里面主要的问题是认为CGI::Session是可以独立使用的,其实不然,因为我们知道session的两种传递形式就是get url和cookie,因此在第一个页面创建session的时候必须也要将次session id通过url或者cookie传抵给以后的页面,当以后的页面在执行的时候流览器将自动将同一个域的cookie传到服务器上,然后我们利用new CGI可以得到这个session id,因此就可以通过/tmp文件夹下的session文件取到value了

当然,这个例子仅仅演示了coockie session的使用,但是同样有借鉴意义的

在这几天的帖子里面有一位同志错误将new session里面第二个参数置为undef,其实这相当于又重建了一次session,跟前一个页面建的session完全失去联系,所以最后得到的f_name值是不存在的

归根结底,session其实是一个记录了此次会话的一些特有信息的文件(或者数据库行,当使用不同的session driver时),如果没有将session id互相传递来判断的话是无法得到相应信息的
 :)



 flw 回复于:2005-01-13 15:15:14

请专家鉴定一下,
有望成为精华。


 superdoctor 回复于:2005-01-13 15:19:34

谢谢flw

其实也不特别要求,不过看到问的人的确很多,希望加成精华后便于查找罢了


 flw 回复于:2005-01-13 15:28:58

可惜我不懂 CGI……


 apile 回复于:2005-01-13 15:39:48

不錯呀...很好...
我用perl寫CGI..但是不用CGI pm..:)
也很少用session...
但是看起來應該沒錯....:)


 superdoctor 回复于:2005-01-13 15:52:24

:) ,程序我测过,没有问题的,呵呵


 Osment 回复于:2005-01-13 18:04:05

支持一把:) 
8过如果用文本  Session 的话,建议用Firzen <firzen@perlchina.org>;. 老兄写的DiGiSession,比CGI::Session模块效率高一点。


 望尘莫及 回复于:2005-01-14 09:27:14

现在看不懂,先存下来^_^


 yzcdf 回复于:2005-01-18 19:19:07

楼上的,好主意,赞成!


 yzcdf 回复于:2005-01-24 09:30:08

终于找到这里了
superdoctor,我想问一下
在1.pl里面必须写一下代码吗?
print "<script language='javascript'>;"; 
print " location.href='2.pl';"; 
print "</script>;"; 
就是说,在设置Session时,必须设置Session的文件?
我的情况是这样的,比如有一个论坛,
在首页输入用户名密码登录
然后登录到另外一个网页a,
这个是一个框架网页,它包括两个两个网页(b、c),是上下结构的,
上面的网页b是主要的菜单(功能),
具体的功能显示在下面c,
比如b网页有5个功能
那么就会对应5个不同的网页要在c网页显示
我想在a网页设置好Session后,
在这5个不同的网页都可以取到Session的值,
甚至在5个不同的网页的连接网页中随时都可以取到Session的值
这样能实现吗?
请高手版我分析一下
谢谢!


 superdoctor 回复于:2005-01-24 15:14:26

不必写那个javascripts,那是我做例子用的

不管什么框架 都可以用,只要你没有跨域就可以取道session里面的值


 yzcdf 回复于:2005-01-26 11:18:39

关于1.pl
我的代码如下:
#!c:/perl/bin/perl
require "tysz.pl";
print &PrintHeader;

use CGI;

use CGI::session;
my $cgi = new CGI; 
my $session = new CGI::Session("driver:File", $cgi , {Directory=>;'/tmp'});
my $cookie = $cgi->;cookie(CGISESSID =>; $session->;id ); 
print $cgi->;header(-cookie=>;$cookie); 
$session->;param('sess_user_name',$name); 
因为我的网页上要有些中文,所以必须输出一个"头儿"
再这里我用的是print &PrintHeader;
然后楼主的代码:print $cgi->;header(-cookie=>;$cookie); 
就会输出Set-Cookie: CGISESSID=25c3e138d300831db01ec4a54e837222; path=/ Date: Wed, 26 Jan 2005 03:16:02 GMT Content-Type: text/html; charset=ISO-8859-1
我想代码里的print可以省略,楼主认为呢?
但是我省略以后,
在后面的文家里还是不能取出Session的值,
代码如下:
#!c:/perl/bin/perl
require "tysz.pl";
print &PrintHeader;

print "begin<br>;";
use CGI;
use CGI::Session;
my $cgi = new CGI; 

my $session = new CGI::Session("driver:File", $cgi, {Directory=>;'/tmp'}); 

my $user_name = $session->;param("sess_user_name");
print "session_user_name is:$user_name<br>;";

楼主,帮忙看看,谢谢了~~


 superdoctor 回复于:2005-01-27 09:07:56

省略print就无法将cookie放置到客户端了,当然就取不到session值!


 yzcdf 回复于:2005-01-27 13:54:54

我有print的时候,也取不出来Session的值
写这个两段代码需要注意什么?
能给我说一下你的使用环境吗?
你是怎么测试这两段代码的?
为什么我还是搞不定?OH MY GOD!


 superdoctor 回复于:2005-01-27 15:28:25

没有什么需要特别注意的,当然你的浏览器一定是要打开cookie的

其他的就没有什么需要特别说明的,你是直接用我的代码还是自己又 改了一下,如果有改动你将程序post上来我看看


 yzcdf 回复于:2005-01-27 16:31:25

非常感谢仁兄! :em16: 
首先说我用的是win2000 server+apache,浏览器是IE6
奇怪的是我在浏览器的安全设置里面找不到关于Cookie的设置
但我以前的程序可以使用Cookie
言规正传
第一个文件是一个简单的form表单,没有什么说的
第二个文件,如下:

#!c:/perl/bin/perl
require "tysz.pl";
print &PrintHeader;

use CGI;
$query=new CGI;
$name=$query->;param('name');
print "name is:$name<br>;"; #在这里可以把上一个网页的文本框的值取出来

#下面我想设置一个Session
use CGI::session;
my $cgi = new CGI; 

my $session = new CGI::Session("driver:File", $cgi , {Directory=>;'/tmp'});
my $cookie = $cgi->;cookie(CGISESSID =>; $session->;id ); 
print $cgi->;header(-cookie=>;$cookie); 
#$cgi->;header(-cookie=>;$cookie); 
$session->;param('sess_user_name','name'); 

my $user_name = $session->;param("sess_user_name");
print "session_user_name is:$user_name<br>;"; #在这里可以输出值,我觉得是设置好了
#下面也是一个简单的表单,供测试用的
print <<XWP;
<html>;
<head>;
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">;
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">;
<meta name="ProgId" content="FrontPage.Editor.Document">;
<title>;New Page 1</title>;
</head>;
<body>;
<p>;<a href="/cgi-bin/session3.plx">;session3</a>;</p>;
<form method="POST" action="/cgi-bin/session3.plx">;
  <p>;<input type="text" name="name" size="20">;</p>;
  <p>;<input type="submit" value="提交" name="B1">;<input type="reset" value="全部重写" name="B2">;</p>;
</form>;
</body>;
</html>;
XWP


第三个文件,如下:

#!c:/perl/bin/perl
require "tysz.pl";
print &PrintHeader;

print "begin<br>;";
use CGI;
$query=new CGI;
$name=$query->;param('name');
print "name is:$name<br>;"; #在这里可以把前一个文本框的值取出来

#下面是想取Session值,就是取不出来
use CGI::Session;
my $cgi = new CGI; 

my $session = new CGI::Session("driver:File", $cgi, {Directory=>;'/tmp'}); 

my $user_name = $session->;param("sess_user_name");
print "session_user_name is:$user_name<br>;";



谢谢了~~


 superdoctor 回复于:2005-01-28 09:44:23

cookie的设置不在internet选项的安全里,而是在隐私->;高级里面,你先将策略设为提示,然后执行程序,看是否将一个包含sessionid的cookie放到了你的浏览器上


 yzcdf 回复于:2005-01-28 10:23:53

我在“高级隐私策略设置”
将“覆盖自动cookie处理”的复选框打了对钩
然后第一方Cookie和第三方Cookie都选的“提示”
“总是允许回话cookie”没有选
确定后,每次在论坛里更换页面的时候,都有一个
“允许Cookie”“禁止Cookie”“详细信息”“帮助”的提示对话框
引用:原帖由 "superdoctor"]看是否将一个包含sessionid的cookie放到了你的浏览器上
 发表:


是在C:\Documents and Settings\Administrator\Cookies目录下,
在那里没有发现和我的设置相关的cookie
顺便问一下,我怎么把计算机上截图放到流言板上去?
那样你看着也许更清楚。


 superdoctor 回复于:2005-01-28 11:04:44

那就没什么问题了,你找不到cookie 不在本帖的讨论范围

你在执行plx的时候IE地址栏都是什么?是不是都是同一个域啊,比如都是
www.a.com/cgi-bin/xxx.plx啊?


 yzcdf 回复于:2005-01-28 11:50:13

对啊,
都是一个域
都是http://192.168.1.10/cgi-bin/xx.plx这样的
我能找到baidu、Chinaunix的Cookie都能找到
就是没有我的那个
我再看看!
我原来的一个程序可以设置Cookie
但在有的机器上不太好用
就是他第一次登录的时候取不到Cookie
但第二次登录就可以取到
能不能帮我看看这是什么问题?


 superdoctor 回复于:2005-01-29 09:04:58

从你的现象来看应该是可以取到的,至于cookie的一些判断这个我没有遇到过,这样,你直接拿我的那个程序来执行可以取到值么?


 yzcdf 回复于:2005-01-31 09:22:15

我怎么才能直接测试你的程序呢?


 superdoctor 回复于:2005-01-31 17:17:31

就象执行你的文件一样啊!

就是我第一页的程序


 yzcdf 回复于:2005-02-01 09:51:10

当我执行第一的文件后,在C:\Documents and Settings\Administrator\Cookies目录下,
发现了administrator@cgi-bin[2]个文件,但看不懂里面所写的内容,而且也没得到Session的值
我想看看这个文件到底是不是1.pl产生,于是
我把文件删除,又执行了一下1.pl
奇怪的是,这次没有产生administrator@cgi-bin[2]文件
这是怎么回事?不会只产生一次吧
研究ing!


 superdoctor 回复于:2005-02-01 19:45:53

我没有在win下使用CGI 模块的经验,不过产生的SESSION文件是明文和可以阅读的,如果没有在指定路径下发现这个文件,你最好查看一下web服务器的日志,看是否有什么出错提示


 yzcdf 回复于:2005-02-02 08:43:19

感谢多次恢复,我先看看,
有问题再向您请教!


 m0925j 回复于:2005-03-28 11:25:55

superdoctor你好,我运行你给的例子的时候打印不出$strName
apache报错是:
[Mon Mar 28 11:16:48 2005] [error] [client 127.0.0.1] Can't locate auto/CGI/Session/autosplit.ix in @INC (@INC contains: C:/Perl/lib C:/Perl/site/lib .) at C:/Perl/lib/AutoLoader.pm line 160.
[Mon Mar 28 11:16:48 2005] [error] [client 127.0.0.1]  at C:/Perl/lib/CGI/Session.pm line 9
这是为什么啊?


 tiger212 回复于:2005-05-07 22:49:46

楼上的把"CGISESSID"用引号引起来就行了


 tiger212 回复于:2005-05-07 22:50:59

本人也是新手,最近在做个perl程序,楼主的code给我启发不小啊.多谢了.


 firzen 回复于:2005-08-28 11:38:19

http://backpan.perl.org/authors/id/F/FI/FIRZEN/


 sessior 回复于:2006-02-07 10:35:00

如果你是PERL高手,请联系我,我是一家美资猎头。目前受一家世界级的软件公司委托找寻Senior Unix Developer,需要懂PERL,熟悉HTML, CGI, XML,熟悉webservers或sockets等等。薪资优厚。如有意者请加MSN:sessior@hotmail.com或致电13916394366陈先生




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=482234
转载请注明作者名及原文出处



收藏本页到: