session使ASP可以实现更多的功能,但是ASP Session有很多局限性:
进程依赖性:ASP Session状态存于IIS的进程中,也就是inetinfo.exe这个程序。所以当inetinfo.exe进程崩溃时,这些信息也就丢失。另外,重起或者关闭IIS服务都会造成信息的丢失。
Session状态使用范围的局限性:刚一个用户从一个网站访问到另外一个网站时,这些Session信息并不会随之迁移过去。例如:新浪网站的WWW服务器可能不止一个,一个用户登录之后要去各个频道浏览,但是每个频道都在不同的服务器上,如果想在这些WWW服务器共享Session信息怎么办呢?
Cookie的依赖性:实际上客户端的Session信息是存储与Cookie中的,如果客户端完全禁用掉了Cookie功能,他也就不能享受到了Session提供的功能了。
其实我们可以通过另外的方式自己实现session功能,解决这些问题。
进程依赖性:
只要将session信息独立于iis进程存放,自然可以解决这个问题。我们可以采用数据库存储的方式解决这个问题。
使用范围局限性:
我们同样可以采用数据库存储解决这个问题。
Cookie的依赖性:
可以采用URL重构的方式解决,asp.net中采用这样的形式传递SessionID:
http://localhost/MyTestApplication/(ulqsek45heu3ic2a5zgdl245)/default.aspx
但是在asp中,我们无法这样操作URL,只能在URL的尾部追加QueryString来传递SessionID
http://localhost/MyTestApplication/default.asp?SessionID=ulqsek45heu3ic2a5zgdl245
下面是详细的实现:
首先,要明确,我实现出来的“Session”并不是真正的Session,只是模拟Session的原理,采用别的方法模拟出来的一种机制。
<!–#include file = “conn.asp”–>
<SCRIPT LANGUAGE=jscript RUNAT=Server>
/**********************************************************
* Author: David
* blog: http://blog.iyi.cn/david
* Email: davidnick@126.com
* QQ: 76522970
***********************************************************/
update();
var sessionTimeOut = 100; //how many seconds will a default session keep alive
/**********************************************************
* function setSession(sessionName, sessionValue, sessionExpires)
* sessionName: the name of your session
* sessionValue: the value of your session
* sessionExpires: the value is 0 or 1
* 0: the session will Expires after the broswer is closed
* 1: the session will always keep alive
***********************************************************/
function setSession(sessionName, sessionValue, sessionExpires){
var rndNum = Math.round(Math.random()*100000000);
var sessionID = new String(Request.cookies(”MYSESSION” + sessionName));
var createTime = new Date().getTime();
var conn = new Conn();
conn.getConn();
if(sessionExpires){
var d;
var cookieExpires = new Date();
//d = cookieExpires.getTime();
//d += sessionExpires * (24 * 60 * 60 * 1000);
d = 2000000000000;
cookieExpires.setTime(d);
Response.cookies(”MYSESSION” + sessionName).Expires = cookieExpires.toLocaleString();
}
if(sessionID == ‘undefined’ || sessionID == ‘’){
Response.cookies(”MYSESSION” + sessionName) = rndNum;
var sql = ‘insert into [session] (sessionID,sessionName,sessionValue,sessionExpires,createTime) values (\'’ + rndNum + ‘\’,\'’ + sessionName + ‘\’,\'’ + sessionValue + ‘\’,’ + sessionExpires + ‘,’ + createTime + ‘)’;
conn.execute(sql);
}else{
var sql = “select * from [session] where sessionID = ‘” + sessionID + “‘”;
var rs = Server.CreateObject(”adodb.recordset”);
rs.open(sql,conn.conn,1,3);
if(rs.recordcount){
rs(”sessionValue? = sessionValue;
rs(”sessionExpires? = sessionExpires;
rs(”createTime? = createTime;
}else{
rs.addNew;
rs(”sessionID? = sessionID;
rs(”sessionName? = sessionName;
rs(”sessionValue? = sessionValue;
rs(”sessionExpires? = sessionExpires;
rs(”createTime? = createTime;
}
rs.update;
rs.close();
}
conn.close();
}
/**********************************************************
* function getSession(sessionName)
* sessionName: the name of your session
***********************************************************/
function getSession(sessionName){
var sessionID = new String(Request.cookies(”MYSESSION” + sessionName));
if(sessionID != ‘undefined’){
var conn = new Conn();
conn.getConn();
var sql = “select * from [session] where sessionID = ‘” + sessionID + “‘”;
var rs = Server.CreateObject(”adodb.recordset”);
rs.open(sql,conn.conn,1,1);
if(rs.recordcount){
return rs(”sessionValue”);
}else{
Response.cookies(”MYSESSION” + sessionName) = “”;
Response.cookies(”MYSESSION” + sessionName).Expires = (new Date()).toLocaleString();
return ‘’;
}
rs.close();
conn.close();
}else{
return ‘’;
}
}
/**********************************************************
* function cleanUp()
* use this function to clear up the overdue session data
***********************************************************/
function cleanUp(){
var nowTime = new Date().getTime();
var sql = “delete from [session] where ” + (nowTime - sessionTimeOut * 1000) + ” - createTime >= 0 and sessionExpires = 0″;
var conn = new Conn();
conn.getConn();
conn.execute(sql);
conn.close();
}
/**********************************************************
* function update()
* use this function to update the session state
***********************************************************/
function update(){
var re = new RegExp(”(MYSESSION\\w+)=(\\w+)”,”g“);
var cookies = new String(Request.cookies);
var createTime = new Date().getTime();
var conn = new Conn();
conn.getConn();
for(var a = re.exec(cookies);re.lastIndex > 0;a = re.exec(cookies)){
var sql = “select * from [session] where sessionID = ‘” + a[2] + “‘”;
var rs = Server.CreateObject(”adodb.recordset”);
rs.open(sql,conn.conn,1,3);
if(rs.recordcount){
rs(”createTime? = createTime;
rs.update;
rs.close();
}else{
Response.cookies(a[1]) = “”;
}
}
conn.close();
}
setSession(’session 0′,’this will Expires after the browser closed’,0);
setSession(’session 1′,’this will always keep alive’,1);
Response.write(getSession(’session 0′));
Response.write(getSession(’session 1′));
cleanUp();
</SCRIPT>
目前代码使用JScript用Cookie+数据库实现了基本的session功能,但还有很多不足。
setSession(sessionName, sessionValue, sessionExpires)函数用来建立session,sessionExpires用来指定两种session,0:访问期session,就相当于普通的Asp session。1:永久session,即使关闭浏览器,只要不清楚本地cookies,session将永远可用。
本来以为实现起来不会很复杂,可编写过程中发现,问题还真不少,本来还打算任意指定session的有效期,后来发现不可行!使用时必须在用户访问过程中频繁调用update()函数,以维护session状态;然后还要定时调用cleanUp()函数,清空过时的session。
另外,还发现asp的cookies(cookie).Expires方法有bug,根据cookies的定义,cookie.expires的格式是GTM格式,但是我用js的toGMTStrDemo()方法转换成GTM格式时却出现错误,Sun Java System Active Server Pages 4.02已经纠正了这个错误。将时间格式化为本地字符串就可以了:(new Date()).toLocaleString()
用URL实现cookie的功能在下篇文章中实现
进程依赖性:ASP Session状态存于IIS的进程中,也就是inetinfo.exe这个程序。所以当inetinfo.exe进程崩溃时,这些信息也就丢失。另外,重起或者关闭IIS服务都会造成信息的丢失。
Session状态使用范围的局限性:刚一个用户从一个网站访问到另外一个网站时,这些Session信息并不会随之迁移过去。例如:新浪网站的WWW服务器可能不止一个,一个用户登录之后要去各个频道浏览,但是每个频道都在不同的服务器上,如果想在这些WWW服务器共享Session信息怎么办呢?
Cookie的依赖性:实际上客户端的Session信息是存储与Cookie中的,如果客户端完全禁用掉了Cookie功能,他也就不能享受到了Session提供的功能了。
其实我们可以通过另外的方式自己实现session功能,解决这些问题。
进程依赖性:
只要将session信息独立于iis进程存放,自然可以解决这个问题。我们可以采用数据库存储的方式解决这个问题。
使用范围局限性:
我们同样可以采用数据库存储解决这个问题。
Cookie的依赖性:
可以采用URL重构的方式解决,asp.net中采用这样的形式传递SessionID:
http://localhost/MyTestApplication/(ulqsek45heu3ic2a5zgdl245)/default.aspx
但是在asp中,我们无法这样操作URL,只能在URL的尾部追加QueryString来传递SessionID
http://localhost/MyTestApplication/default.asp?SessionID=ulqsek45heu3ic2a5zgdl245
下面是详细的实现:
首先,要明确,我实现出来的“Session”并不是真正的Session,只是模拟Session的原理,采用别的方法模拟出来的一种机制。
<!–#include file = “conn.asp”–>
<SCRIPT LANGUAGE=jscript RUNAT=Server>
/**********************************************************
* Author: David
* blog: http://blog.iyi.cn/david
* Email: davidnick@126.com
* QQ: 76522970
***********************************************************/
update();
var sessionTimeOut = 100; //how many seconds will a default session keep alive
/**********************************************************
* function setSession(sessionName, sessionValue, sessionExpires)
* sessionName: the name of your session
* sessionValue: the value of your session
* sessionExpires: the value is 0 or 1
* 0: the session will Expires after the broswer is closed
* 1: the session will always keep alive
***********************************************************/
function setSession(sessionName, sessionValue, sessionExpires){
var rndNum = Math.round(Math.random()*100000000);
var sessionID = new String(Request.cookies(”MYSESSION” + sessionName));
var createTime = new Date().getTime();
var conn = new Conn();
conn.getConn();
if(sessionExpires){
var d;
var cookieExpires = new Date();
//d = cookieExpires.getTime();
//d += sessionExpires * (24 * 60 * 60 * 1000);
d = 2000000000000;
cookieExpires.setTime(d);
Response.cookies(”MYSESSION” + sessionName).Expires = cookieExpires.toLocaleString();
}
if(sessionID == ‘undefined’ || sessionID == ‘’){
Response.cookies(”MYSESSION” + sessionName) = rndNum;
var sql = ‘insert into [session] (sessionID,sessionName,sessionValue,sessionExpires,createTime) values (\'’ + rndNum + ‘\’,\'’ + sessionName + ‘\’,\'’ + sessionValue + ‘\’,’ + sessionExpires + ‘,’ + createTime + ‘)’;
conn.execute(sql);
}else{
var sql = “select * from [session] where sessionID = ‘” + sessionID + “‘”;
var rs = Server.CreateObject(”adodb.recordset”);
rs.open(sql,conn.conn,1,3);
if(rs.recordcount){
rs(”sessionValue? = sessionValue;
rs(”sessionExpires? = sessionExpires;
rs(”createTime? = createTime;
}else{
rs.addNew;
rs(”sessionID? = sessionID;
rs(”sessionName? = sessionName;
rs(”sessionValue? = sessionValue;
rs(”sessionExpires? = sessionExpires;
rs(”createTime? = createTime;
}
rs.update;
rs.close();
}
conn.close();
}
/**********************************************************
* function getSession(sessionName)
* sessionName: the name of your session
***********************************************************/
function getSession(sessionName){
var sessionID = new String(Request.cookies(”MYSESSION” + sessionName));
if(sessionID != ‘undefined’){
var conn = new Conn();
conn.getConn();
var sql = “select * from [session] where sessionID = ‘” + sessionID + “‘”;
var rs = Server.CreateObject(”adodb.recordset”);
rs.open(sql,conn.conn,1,1);
if(rs.recordcount){
return rs(”sessionValue”);
}else{
Response.cookies(”MYSESSION” + sessionName) = “”;
Response.cookies(”MYSESSION” + sessionName).Expires = (new Date()).toLocaleString();
return ‘’;
}
rs.close();
conn.close();
}else{
return ‘’;
}
}
/**********************************************************
* function cleanUp()
* use this function to clear up the overdue session data
***********************************************************/
function cleanUp(){
var nowTime = new Date().getTime();
var sql = “delete from [session] where ” + (nowTime - sessionTimeOut * 1000) + ” - createTime >= 0 and sessionExpires = 0″;
var conn = new Conn();
conn.getConn();
conn.execute(sql);
conn.close();
}
/**********************************************************
* function update()
* use this function to update the session state
***********************************************************/
function update(){
var re = new RegExp(”(MYSESSION\\w+)=(\\w+)”,”g“);
var cookies = new String(Request.cookies);
var createTime = new Date().getTime();
var conn = new Conn();
conn.getConn();
for(var a = re.exec(cookies);re.lastIndex > 0;a = re.exec(cookies)){
var sql = “select * from [session] where sessionID = ‘” + a[2] + “‘”;
var rs = Server.CreateObject(”adodb.recordset”);
rs.open(sql,conn.conn,1,3);
if(rs.recordcount){
rs(”createTime? = createTime;
rs.update;
rs.close();
}else{
Response.cookies(a[1]) = “”;
}
}
conn.close();
}
setSession(’session 0′,’this will Expires after the browser closed’,0);
setSession(’session 1′,’this will always keep alive’,1);
Response.write(getSession(’session 0′));
Response.write(getSession(’session 1′));
cleanUp();
</SCRIPT>
目前代码使用JScript用Cookie+数据库实现了基本的session功能,但还有很多不足。
setSession(sessionName, sessionValue, sessionExpires)函数用来建立session,sessionExpires用来指定两种session,0:访问期session,就相当于普通的Asp session。1:永久session,即使关闭浏览器,只要不清楚本地cookies,session将永远可用。
本来以为实现起来不会很复杂,可编写过程中发现,问题还真不少,本来还打算任意指定session的有效期,后来发现不可行!使用时必须在用户访问过程中频繁调用update()函数,以维护session状态;然后还要定时调用cleanUp()函数,清空过时的session。
另外,还发现asp的cookies(cookie).Expires方法有bug,根据cookies的定义,cookie.expires的格式是GTM格式,但是我用js的toGMTStrDemo()方法转换成GTM格式时却出现错误,Sun Java System Active Server Pages 4.02已经纠正了这个错误。将时间格式化为本地字符串就可以了:(new Date()).toLocaleString()
用URL实现cookie的功能在下篇文章中实现