2008年9月15日星期一

PHP防刷新

session_start();
$k=$_GET['k'];
$t=$_GET['t'];
$allowTime = 1800;//防刷新时间
$ip = get_client_ip();
$allowT = md5($ip.$k.$t);
if(!isset($_SESSION[$allowT]))
{
$refresh = true;
$_SESSION[$allowT] = time();
}elseif(time() - $_SESSION[$allowT]>$allowTime){
$refresh = true;
$_SESSION[$allowT] = time();
}else{
$refresh = false;
}
?>

ASP防刷新重复提交、防后退方法

提交后禁用提交按钮(大部分人都是这样做的)

如果客户提交后,按F5刷新怎么办?

使用Session

在提交的页面也就是数据库处理之前:



if session("ok")=true then
response.write "错误,正在提交"
response.end
end if

数据处理完后,修改session("ok")=false。

数据处理成功马上Redirect到另外一个页面

操作后刷新的确是个问题,你可以使用跳转页面、关闭本页面,如果是有参数据条件来控制的,那就应该好做了,可以直接修改window.location的值,把参数全部改掉,这样就差不多了。

缺点:简单地运用Response.Redirect将不再有效,因为用户从一个页面转到另一个页面,我们都必须用客户端代码清除location.history。注意,这种方法清除的是最后一个访问历史记录,而不是全部的访问记录。 点击后退按钮,再点击后退按钮,你可以看到这时打开的是本页面之前的页面!(当然,这是在你的客户端启用了JavaScript功能的条件下。)

如果客户按后退,怎么办?

防止网页后退--禁止缓存

我们在进行数据库添加操作的时候,如果允许后退,而正巧有刷新了页面,就会再次执行添加操作,无疑这不是我们需要的,像一般网上很多禁止缓存的代码,有时并不可靠,这时你只要在操作的页面加上就可以了,在网页的里指定要定向的新页,再点后退,看是不是不会再退到刚才的操作页面了,实际上已经把这个历史给删除了

ASP:
Response.Buffer = True
Response.ExpiresAbsolute = Now() - 1
Response.Expires = 0
Response.CacheControl = "no-cache"
ASP.NET:
Response.Buffer=true;
Response.ExpiresAbsolute=DateTime.Now.AddSeconds(-1);
Response.Expires=0;
Response.CacheControl="no-cache";
究竟怎样才能"禁用"浏览器的后退按钮?或者“怎样才能防止用户点击后退按钮返回以前浏览过的页面?”

遗憾的是,我们无法禁用浏览器的后退按钮。

防止网页后退--新开窗口

用window.open弹出表单页面,点提交后关闭该页;处理提交的ASP页也是用弹出,设定表单的target,点提交时window.open("XXX.asp","_blank"),然后用JS来提交表单,完成后window.close();
简单的说,就是提交表单的时候弹出新窗口,关闭本窗口。对于window.open()打开的窗口怎么后退?能后退到哪里去?

呵呵,罗嗦了一堆废话,知道怎么处理了么?混合运用客户端脚本和服务器端脚本。

Discuz 通行证的制作方法和详细说明

通行证是个大题目,说白了也就是如何维护客户的会话,在php中所能用的方法无非几种:

● Cookie
● Session
● POST或GET的方法传值

一般中小型的单服务器应用程序站点,如Discuz论坛,采用的cookie+session+mysql的方法来维持用户会话。

考虑到网站规模和复杂性,例如多台服务器多个应用程序,例如163的通行证系统,登陆成功后会在客户端写一个cookie,里面保存用户名等信息。其他应 用程序,都是通过读取这个Cookie重新将客户带入自己的会话中,重而实现通行证功能。163的这种做法不失为一种好办法。

Discuz! Passport 接口技术文档


从 Discuz! 4.0.0 版本开始,Discuz! 内嵌了一个独特的 Passport(通行证) 接口,利用此接口,用户将很容易将论坛与其他应用程序整合,而实现统一登录与退出、用户数据共享、积分同步等功能。可以整合的应用程序包括内容管理系统(CMS)、商城系统、游戏系统等等,如您对这方面功能有兴趣或有需求,请继续阅读本文档。

Discuz! Passport 的优点

Discuz! Passport 系统使用了 Discuz! 独有的技术,并不等同于以往使用过的一些方法,与传统的实现方式相比,具备(不限于)以下优势:


基于私有密匙的低相关性可逆加密算法,配合 MD5 校检码技术,使得暴力破解或伪造几乎不可能。
应用程序可与论坛放置于不同的服务器及不同的域名下。可基于不同操作系统、不同程序语言和不同数据库平台,具备真正的平台无关性。
不需要任何形式的数据库连接、或强制把两套应用程序的数据放在同一数据库甚至同一数据表中。论坛与应用程序都有各自的用户数据表,只是在需要时进行无缝同步操作。
对应用程序的代码改动简便易行,可最快速的完成应用程序与论坛间的整合。
Discuz! Passport 的局限

您在开始利用 Discuz! Passport 进行二次开发时,需要了解这个系统的局限性,以对未来的工作进行正确的评估与安排。

只能工作在用户密码不加密、可逆加密或 MD5 加密的情况下,否则论坛后台无法登录。
只能与一种应用程序关联,即二方关联。不能实现三方关联或与更多的应用程序进行关联。
应用程序需具有独立的注册、登录、退出页面和链接,否则需要自行修改论坛中的相应表单或程序。
由于论坛的注册人数可能很多,例如百万级以上,且应用程序和论坛间的用户数据是同步的,因此要求应用程序能够稳定的负载大量用户的访问。


Discuz! Passport 原理与流程


假设已设置如下变量或参数

挂接 Discuz! Passport 的应用程序假设为一套 PHP 语言编写的 CMS 系统
Discuz! 的 URL 为 http://www.myforums.com
应用程序的 URL 为 http://www.mywebsite.com
应用程序的注册页面为 http://www.mywebsite.com/register.php
应用程序的登录页面为 http://www.mywebsite.com/login.php?action=login
应用程序的退出页面为 http://www.mywebsite.com/login.php?action=logout
开启通行证后的用户登录流程


如果用户在论坛点击“登录”,则转向到事先设置好的应用程序登录页面(http://www.mywebsite.com/login.php?action=login),并在登录页面的 URL 中加入参数 forward(加入 forward 后的链接例如 http://www.mywebsite.com/login.p ... orums.com/index.php),用于在登录后将用户导向到指定的 URL。


应用程序收到此请求后,按照惯例生成表单,并增加一个表单变量 ,将 GET 方式传递过来的 forward 参数通过表单进行传递。


用户在应用程序的表单中填写登录信息,并提交到应用程序的登录验证程序。应用程序验证用户提交的用户名和密码的合法性:


如果不通过:提示用户名密码错误,要求其返回上一页重新填写。


如果通过,需要进行如下操作:


设置自身 Cookie 或 Session,使得应用程序自身处于登录状态。


检查表单中是否提交了 forward 变量,如有,则意味着登录请求可能是由论坛而来,将此变量传递到后面的请求中;如没有,自行生成 forward 变量,使得论坛登录后能够跳转回到应用程序中。


通过 header('Location: http://www.myforums.com/api/pass ... /yyy&verify=zzz') 的方式,将登录请求传递到论坛进行处理。其中 auth 用来将用户信息与资料以特定的格式,加密传递给论坛,forward 用于告知论坛 Passport API 完成自身操作后转向到的 URL 地址,verify 用于验证前面两个变量的有效性。auth、forward、verify 格式与结构将在后面进行说明。



Discuz! Passport API 在接收到由应用程序通过 header() 提交过来的请求后,进行如下操作:


根据 verify 判断 auth 和 forward 变量是否合法,如合法则继续,否则终止。


将 auth 根据既定算法解密,并还原成数组,数组的内容与格式将在后面进行说明。根据数组中的内容,检查此用户是否存在。如存在,则根据上述数组中的内容 UPDATE 论坛中相应的用户资料;如不存在,则使用数组中的信息 INSERT 到论坛用户资料表中。


论坛设置 Cookie 或 Session,使得论坛自身处于登录状态。


根据应用程序反馈的 forward 值,通过 header('Location: http://xxx') 的形式将页面跳转到 forward 变量指定的 URL。



至此,登录流程结束
开启通行证后的用户退出流程


如果用户在论坛点击“退出”,则转向到事先设置好的应用程序退出页面(http://www.mywebsite.com/login.php?action=logout),并在登录页面的 URL 中加入参数 forward(例如 http://www.mywebsite.com/login.p ... orums.com/index.php),用于在退出后将用户导向到指定的 URL。


应用程序收到此请求后,清除自身 Cookie 或 Session,使得应用程序自身处于非登录状态。


检查是否提交了 forward 变量,如有,则意味着登录请求可能是由论坛而来,将此变量传递到后面的请求中;如没有,自行生成 forward 变量,使得论坛登录后能够跳转回到应用程序中。


通过 header('Location: http://www.myforums.com/api/pass ... /yyy&verify=zzz') 的方式,将退出请求传递到论坛进行处理。其中 forward 用于告知论坛 Passport API 完成自身操作后转向到的 URL 地址,verify 用于验证 forward 变量的有效性。forward、verify 格式与结构将在后面进行说明。


Discuz! Passport API 在接收到由应用程序通过 header() 提交过来的请求后,进行如下操作:


根据 verify 判断 forward 变量是否合法,如合法则继续,否则终止。


清楚论坛的 Cookie 或 Session,使得论坛自身处于非登录状态。


根据应用程序反馈的 forward 值,通过 header('Location: http://xxx') 的形式将页面跳转到 forward 变量指定的 URL。



至此,退出流程结束。
开启通行证后的用户注册流程


如果用户在论坛点击“注册”,则转向到事先设置好的应用程序注册页面(http://www.mywebsite.com/register.php),并在注册页面的 URL 中加入参数 forward(例如 http://www.mywebsite.com/registe ... orums.com/index.php),用于在注册后将用户导向到指定的 URL


应用程序收到此请求后,按照惯例生成表单,并增加一个表单变量 ,将 GET 方式传递过来的 forward 参数通过表单进行传递


用户在应用程序的表单中填写注册信息,并提交到应用程序的注册验证程序。应用程序验证用户提交信息的完整性和合法性:


如果不通过:提示其问题所在,要求其返回上一页重新填写


如果通过,需要进行如下操作:


将用户资料插入到应用程序自身用户数据库中


设置自身 Cookie 或 Session,使得应用程序自身处于登录状态

检查表单中是否提交了 forward 变量,如有,则意味着注册请求可能是由论坛而来,将此变量传递到后面的请求中;如没有,自行生成 forward 变量,使得论坛注册后能够跳转回到应用程序中


通过 header('Location: http://www.myforums.com/api/pass ... /yyy&verify=zzz') 的方式,将注册请求传递到论坛进行处理。其中 auth 用来将用户信息与资料以特定的格式,加密传递给论坛,forward 用于告知论坛 Passport API 完成自身操作后转向到的 URL 地址,verify 用于验证前面两个变量的有效性。auth、forward、verify 格式与结构将在后面进行说明



Discuz! Passport API 在接收到由应用程序通过 header() 提交过来的请求后,进行如下操作:


根据 verify 判断 auth 和 forward 变量是否合法,如合法则继续,否则终止


将 auth 根据既定算法解密,并还原成数组,数组的内容与格式将在后面进行说明。根据数组中的内容,检查此用户是否存在。如存在,则根据上述数组中的内容 UPDATE 论坛中相应的用户资料;如不存在,则使用数组中的信息 INSERT 到论坛用户资料表中


论坛设置 Cookie 或 Session,使得论坛自身处于登录状态


根据应用程序反馈的 forward 值,通过 header('Location: http://xxx') 的形式将页面跳转到 forward 变量指定的 URL



至此,注册流程结束
本部分中,加下划线显示的部分,是需要对您的应用程序进行更改的部分,事实上,这部分更改会非常容易和方便。


Discuz! Passport 参数规格与加密方式


私有密匙(passport_key)

由于一些关键参数采用了 GET 方式进行传递,即便两次 header 跳转并不会直接将链接显示在外面,但我们仍然对关键的参数进行了加密,私有密匙共有两个作用:其一是供下面提到的可逆加密算法(AzDGCrypt)进行 数据的加解密;其二是生成不可逆验证字串(verify),以防止关键信息被伪造。

在启用 Discuz! Passort 后,您需要在应用程序和 Discuz! 后台配置两处私有密匙,这两处的内容必须完全相同,这样应用程序和论坛之间才能正常通信。私有密匙决定了加密算法的强度,因此密匙长度请不要小于 10 个字节,并包含字母、数字和符号,以保证系统的安全。

加密算法

Discuz! Passport 采用 Azerbaijan Development Group(AzDG)开发的可逆加密算法 AzDGCrypt 对用户资料进行加密。如提供正确的私有密匙,可通过本加密算法对数据进行加密及解密,因此只要保证私有密匙的保密性,即可确保数据传递过程中的安全。以下 为 Discuz! Passport 中应用到的可逆加密算法,为了生成可以被 Discuz! Passport 正确解密的 auth 字串,需要将如下函数放置于应用程序中,并可在登录及注册时调用。

passport_encrypt()是加密函数,用法为 passport_encrypt($txt, $key),其中 $txt 是待加密的字串,$key 是私有密匙。
passport_decrypt()是解密函数,用法为 passport_decrypt($txt, $key),其中 $txt 是加密后的字串,$key 是私有密匙。


/**
* Passport 加密函数
*
* @param string 等待加密的原字串
* @param string 私有密匙(用于解密和加密)
*
* @return string 原字串经过私有密匙加密后的结果
*/
function passport_encrypt($txt, $key) {

// 使用随机数发生器产生 0~32000 的值并 MD5()
srand((double)microtime() * 1000000);
$encrypt_key = md5(rand(0, 32000));

// 变量初始化
$ctr = 0;
$tmp = '';

// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
for($i = 0; $i < strlen($txt); $i++) {
// 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
// $tmp 字串在末尾增加两位,其第一位内容为 $encrypt_key 的第 $ctr 位,
// 第二位内容为 $txt 的第 $i 位与 $encrypt_key 的 $ctr 位取异或。然后 $ctr = $ctr + 1
$tmp .= $encrypt_key[$ctr].($txt[$i] ^ $encrypt_key[$ctr++]);
}

// 返回结果,结果为 passport_key() 函数返回值的 base65 编码结果
return base64_encode(passport_key($tmp, $key));

}

/**
* Passport 解密函数
*
* @param string 加密后的字串
* @param string 私有密匙(用于解密和加密)
*
* @return string 字串经过私有密匙解密后的结果
*/
function passport_decrypt($txt, $key) {

// $txt 的结果为加密后的字串经过 base64 解码,然后与私有密匙一起,
// 经过 passport_key() 函数处理后的返回值
$txt = passport_key(base64_decode($txt), $key);

// 变量初始化
$tmp = '';

// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
for ($i = 0; $i < strlen($txt); $i++) {
// $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
// 与 $txt 的第 $i + 1 位取异或。然后 $i = $i + 1
$tmp .= $txt[$i] ^ $txt[++$i];
}

// 返回 $tmp 的值作为结果
return $tmp;

}

/**
* Passport 密匙处理函数
*
* @param string 待加密或待解密的字串
* @param string 私有密匙(用于解密和加密)
*
* @return string 处理后的密匙
*/
function passport_key($txt, $encrypt_key) {

// 将 $encrypt_key 赋为 $encrypt_key 经 md5() 后的值
$encrypt_key = md5($encrypt_key);

// 变量初始化
$ctr = 0;
$tmp = '';

// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
for($i = 0; $i < strlen($txt); $i++) {
// 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
// $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
// 与 $encrypt_key 的第 $ctr + 1 位取异或。然后 $ctr = $ctr + 1
$tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
}

// 返回 $tmp 的值作为结果
return $tmp;

}

/**
* Passport 信息(数组)编码函数
*
* @param array 待编码的数组
*
* @return string 数组经编码后的字串
*/
function passport_encode($array) {

// 数组变量初始化
$arrayenc = array();

// 遍历数组 $array,其中 $key 为当前元素的下标,$val 为其对应的值
foreach($array as $key => $val) {
// $arrayenc 数组增加一个元素,其内容为 "$key=经过 urlencode() 后的 $val 值"
$arrayenc[] = $key.'='.urlencode($val);
}

// 返回以 "&" 连接的 $arrayenc 的值(implode),例如 $arrayenc = array('aa', 'bb', 'cc', 'dd'),
// 则 implode('&', $arrayenc) 后的结果为 ”aa&bb&cc&dd"
return implode('&', $arrayenc);

}




passport_encode()是将数组转换合成为字串形式存储的函数:变量名和数值之间用等号连接,如果数值包含特殊字符,使用 urlencode() 将其转码;多个变量间使用 & 分割。例如原始数组内容为 array('username' => 'abc', 'email' => 'my+discuz@gmail.com'),经过 passport_encode() 编码后结果为 username=abc&email=my%2Bdiscuz%40gmail.com。

信息字串(auth)

应用程序在收到登录或注册请求,并读取到用户资料后,请按如下的要求将用户资料及部分其他信息存放于一个数组之中。数组各键值的含义为:



cookietime
应用程序保存该用户登录记录的时间,可为非负整数,单位秒,Discuz! Passport 收到此参数后,会设置同样的 Cookie 过期时间,这样应用程序和论坛可以保证同样的登录有效性。如不传递此参数,或参数数值不正确,则 Discuz! Passport 按照 0 设置 Cookie 有效期。


time
应用程序所在服务器当前时间(9 或 10 位数字 Unix Timestamp),此参数用于 Discuz! 所在服务器当前时间进行比对,如果早于当前时间超过若干秒(取决于 Discuz! Passport 中的“验证字串有效期”设定),则视为本 auth 内容无效,避免此URL被人得知后可能的安全问题。


username
用户登录或注册的用户名。Discuz! 的注册用户名规则为:
长度 1~15 个字符,不得为空
不得为 c:concon、游客(gb2312 或 big5 内码)、Guest
不得包含 (,)、(*)、(")、([TAB])、([SPACE])、([r])、([n])、(<)、(>)、(&)其中之一

如果应用程序提交过来的用户名不符合上述规则,Passport 将自动去处其中的特殊字符,将过滤后的结果写入数据库中。


password
用户密码经 MD5 不可逆加密后的值。如果此密码使用非 MD5 加密,则应用程序和 Passport 不能正常关联和使用。


email
用户 Email 地址(50 个字节以内)。


isadmin
当前用户是否是应用程序的最高管理员,1=是,0=否。最高管理员的权限,将同步到论坛中去,其他下级管理员的身份将不进行同步,而由最高管理员分别在不同的系统中进行设置。

credits
当前用户在应用程序中的积分值,范围 -2147483648 到 2147483647,如果 Discuz! Passport 中设置了目标积分项,则用户登录时,Passport 会把应用程序传递过来的 credits 值同步到指定的论坛的指定积分项目中


gender
当前用户的性别,1=男,2=女,0=未知。


bday
当前用户的生日,格式 yyyy-mm-dd。


regip
当前用户注册时的 IP 地址。


regdate
当前用户注册的时间(9 或 10 位数字 Unix Timestamp)。


nickname
当前用户的昵称(30 个字节以内,如传递此参数,必须打开相应用户组的昵称权限,否则用户在控制面板中提交个人资料时,会导致昵称失效)。


site
当前用户的主页地址(包含http://)。


qq
当前用户的 QQ 号码。


ICQ
当前用户的 ICQ 账号。


msn
当前用户的 MSN Messenger 账号。


yahoo
当前用户的 Yahoo! Messanger 账号。
以上参数中,以黑体下划线显示的 time、username、password、email 是必须传递的参数,缺少上述参数 Passport 将无法正常工作;其他的参数是可选的,如果不传递某些参数,则 Passport 会进行识别,自动不更新没有传递的参数所在的字段;所有数值,请提供原始值,而非经过反斜线转义(addslashes)后的结果。

把上述信息存放于数组中,假定为如下的形式:


$member = array
(
'cookietime' => 31536000,
'time' => 1117415922,
'username' => 'Abcd',
'password' => 'e2fc714c4727ee9395f324cd2e7f331f',
'email' => 'abcd@efgh.com',
'credits' => 123,
'regip' => '210.120.222.111',
'regdate' => '1012752000',
'msn' => 'email@hotmail.com'
);




将其经过如下的加密变换,即可得到 auth 的值:


$auth = passport_encrypt(passport_encode($member), $passport_key);




其中,passport_encode() 在前文已做了说明,用于将数组内容存放于特定的格式,$passport_key 是私有密匙。

切记:由于 $auth 中可能含有等号、加号等特殊字符,请将 $auth 经过 rawurlencode() 编码后再在 URL 中传递,否则可能会产生问题。

导向字串(forward)

导向字串用于通知 Discuz! Passport 在完成自身操作后,返回到哪一个 URL 地址,例如 http://www.myforums.com/forumdisplay.php?fid=2。如果 forward 为空,则默认导向到应用程序的首页

切记:由于 $forward 中可能含有冒号、问号、等号等特殊字符,请将 $forward 经过 rawurlencode() 编码后再在 URL 中传递,否则可能会产生问题。

验证字串(verify)

验证字串用户检验 auth 和 forward 两个参数的合法性,避免非法构造参数进行破坏的可能。无论 auth 和 forward 变量是否存在,验证字串(verify)的值均为:


$verify = md5($action.$auth.$forward.$passport_key);




其中,$action 是当前执行的 Passport 操作,如 login 等等;$auth 是用户信息加密后,并经 rawurlencode() 之前的内容;$forward 是经 rawurlencode() 前的导向字串;$passport_key 是私有密匙。如果 verify 的值不匹配,则 Passport 拒绝进行下一步操作。


Discuz! Passport 设置与启用


内置关联

Discuz! 以战略合作的方式,与业内知名的产品实现了 Passport 关联,目前内置了 SiteEngine 建站引擎(http://www.siteengine.net)和 Shopex 通用型网上商店系统(http://www.shopex.cn)的相关接口,这样用户只须透过在两套软件中简单的设置,即可开启这些关联。

其他应用程序

由于 Discuz! Passport 的高可扩展性和平台无关性,使得您可以参照前文的说明,稍稍改动小部分的代码,便将任何 B/S 模式的应用程序与 Discuz! 进行关联。

参数设置

您可以在 Discuz! 系统设置中,看到相应的通行证设置功能,在 Discuz! 合作伙伴的软件中,也可以找到这些设置入口。相关的操作已比较简单,在此不再详细叙述。

特别说明

如果您先运营了论坛,后与其他应用程序启用了 Passport 关联,由于之前论坛中的用户数据没有同步,您需要先写一个导入程序,将论坛的用户数据导入到应用程序的用户表中,否则以往在论坛注册的用户将无法通过 Passport 登录。已成功关联后新注册的用户无此问题。

在开启了 Discuz! 通行证后,您仍然可以通过 logging.php?action=login 这个链接来登录论坛,以备调试之用,但页面上显示的链接将改为应用程序的登录 URL。注意:开启通行证后,建议您通过 Discuz! 选项关闭论坛本身的注册功能,以免用户通过论坛注册而产生无法同步的问题。

您可以在 Discuz! 的 api/passport.php 找到 Discuz! Passport 的全部源程序,您也许通过他更好的理解 Passport 的原理,更快的完成应用程序与 Discuz! 之间的整合。


典型错误提示


Illegal request

非法请求,当验证字串 verify 不匹配时会产生此提示。可能是应用程序与 Discuz! 配置的私有密匙不同,或是通过 URL 传递前,未将必要的参数(如 auth、forward 等)进行 URL 编码,也有可能是使用了经过 URL 编码的参数值用来计算 verify 的 md5 值造成。以 PHP 语言为例,正确的代码应当是类似于的如下的格式:


$action = 'login';
$auth = passport_encrypt(passport_encode($autharray), $passport_key);
$forward = 'http://www.discuz.net/index.php';
$verify = md5($action.$auth.$forward.$passport_key);

header("Location: http://www.discuz.net/api/passport.php".
"?action=$action".
"&auth=".rawurlencode($auth).
"&forward=".rawurlencode($forward).
"&verify=$verify");


Lack of required parameters

auth 内容解密后,缺少必要的信息 time、username、password、email。

Request expired

请求过期。当前服务器时间与应用程序提交过来的 time 之差大于 Discuz! Passport 中设置的请求有效期。可能是使用以往的代码非法尝试,也可能是由于应用程序和 Discuz! 论坛所在的两台服务器,时间设置有误造成。

Invalid action

没有指定 Passport 所执行的 action。

2008年9月9日星期二

JSP应用语法详解大全3

12)标签:
id="beanInstanceName"
scope="page | request | session | application"
{
class="package.class" |
type="package.class" |
class="package.class" type="package.class" |
beanName="{package.class | }" type="package.class"
}
/>other elements
用于创建一个JavaBeans组件,首先会试图定位一个Bean实例,如果不存在,那么就会从创建一个新的.
属性:
-id="创建的Bean变量名称"
在你所定义的范围中确认Bean的变量,你能在后面的程序中使用此变量名来分辨不同的Bean 这个变量名对大小写敏感,如果这个Bean已经在别的中创建,那么这个id的值必须与原来的那个id值一致.
-scope="page | request | session | application"Bean存在的范围以及id变量名的有效范围.缺省值是page.
13)标签:
type="bean | applet"
code="classFileName"
codebase="classFileDirectoryName"
[ name="instanceName" ]
[ archive="URIToArchive, ..." ]
[ align="bottom | top | middle | left | right" ]
[ height="displayPixels" ]
[ width="displayPixels" ]
[ hspace="leftRightPixels" ]
[ vspace="topBottomPixels" ]
[ jreversion="JREVersionNumber | 1.1" ]
[ nspluginurl="URLToPlugin" ]
[ iepluginurl="URLToPlugin" ] >
[
[
[ ]
[ text message for user ]
用于在浏览器中播放或显示一个对象(典型的就是applet和Bean),而这种显示需要在浏览器的java插件.当Jsp文件被编译,送往浏览器时,标签将会根据浏览器的版本替换成
或者元素.注意用于HTML 4.0 ,用于HTML 3.2.一般来说,这个标签会指定对象是Applet还是Bean,同样也会指定class的名字,还有位置,另外还会指定将从哪里下载这个Java插件.
属性:
-type="bean | applet"将被执行的插件对象的类型,你必须得指定这个是Bean还是applet,因为这个属性没有缺省值.
-code="classFileName"将会被Java插件执行的Java Class的名字,必须以.class结尾,这个文件必须存在于codebase属性指定的目录中.
-codebase="classFileDirectoryName"
将会被执行的Java Class文件的目录(或者是路径),如果你没有提供此属性,使用本标签的JSP文件的目录会被使用.
-name="instanceName"
这个Bean或applet实例的名字,它将会在Jsp其它的地方调用.
-archive="URIToArchive, ..."
一些由逗号分开的路径名,这些路径名用于预装一些将要使用的class,这会提高applet的性能.类似于classpath.
-align="bottom | top | middle | left | right"
图形,对象,Applet的位置.

JSP应用语法详解大全2

8)标签:
转发一个request对象.可以传参,目标文件必须能够处理参数.如果使用非缓冲输
出,而且在使用之前,jsp文件已经有了数据,那么文件执行就会出错.
属性:
-page="URL or 表达式"要转发的文件URL或者是一个代表URL的表达式.
-name参数名value参数值.
9)标签:
+
允许包含动态文件和静态文件,动态的会被Jsp编译器执行.不能从文件名上判断是动态的还是静态的.可以传递参数.
属性:
-page="URL or 表达式"要包含文件的相对路径,或者是代表相对路径的表达.式.
-flush="true"这里你必须使用flush="true",你不能使用false值.缺省值为false.
能传递一个或多个参数给动态文件,能在一个页面中使用多个来传递多个参数.

10)标签:
获得Bean的属性值之前,必须用创建Bean.name指定新建Bean的id.只能JavaBean
属性:
-name="bean的名字"由的id属性指定.
-property="bean的属性"所指定的Bean的属性名.

11)标签:
name="Bean的id"
{
property= "*"
property="propertyName" [ param="parameterName" ]
property="propertyName" value="{string | }"
}/>
的name的值应当于中id的值
多种方法来设定属性值 :
通过用户输入的所有值(被做为参数储存中request对象中)来匹配Bean中的属性
通过用户输入的指定的值来匹配Bean中指定的属性
在运行时使用一个表达式来匹配Bean的属性
属性:
-name="Bean名称"表示已经在中的id设置的Bean变量.
-property="Bean属性名" value="要设置的属性名"如果你使用了property="*",那么Bean的属性没有必要按Html表单中的顺序排序.
-property="*"储存用户在Jsp输入的所有值,用于匹配Bean中的属性.在Bean中的属性的名字必须和request对象中的参数名一致.从客户传到服器上的参数值一般都是字符类型,这些字符串为了能够在Bean中匹配就必须转换成其它的类型,下面的表中列出了Bean属性的类型以及他们的转换方法.把字符串转化为其它
类型的方法,Property 类型方法:
boolean or Boolean
java.lang.Boolean.valueOf(String)
byte or Byte
java.lang.Byte.valueOf(String)
char or Character
java.lang.Character.valueOf(String)
double or Double
java.lang.Double.valueOf(String)
integer or Integer
java.lang.Integer.valueOf(String)
float or Float
java.lang.Float.valueOf(String)
long or Long
java.lang.Long.valueOf(String)

JSP应用语法详解大全1

1)HTML注释:
可以用注释内容,也可以用表达式.
2)隐藏注释:
注释会被JSP编译时被忽略.编译器不会对之间的语句编译,它不会显示在客户的浏览器和源代码中.

3)声明:
声明你将要在JSP程序中用到的变量和方法.可以一次性声明多个变量和方法,要以";"结尾,声明在Java中要合法.

4)表达式:
JAVA中的表达式,会被显示在JSP页面中,注意不要有";".

5)JAVA代码:
包含有效JAVA代码.

6)Include指令:

可以包含HTML,JSP,文本文件,JAVA代码,要注意在这个包含文件中不能使用有时会导致错误.
属性:
file指相对路径,如:"error.jsp""templates/onlinestore.html""/beans/calendar.jsp"
如果这个路径以"/"开头,那么这个路径主要是参照JSP应用的上下关系路径,如果路径是以文件名或目录名开头,那么这个路径就是正在使用的JSP文件的当前路径.

7)Page指令:
属性:
-language="java"
声明脚本语言的种类,暂时只能用"java"
-extends="package.class"
继承一个类
-import="{package.class | package.* }, ..."
导入一个包,下面的包是默认自动导入的.
java.lang.*,javax.servlet.*,javax.servlet.jsp.*,javax.servlet.http.*
-session="true | false"
是否允许session会话,默认true.
-buffer="none | 8kb | sizekb"
设置缓冲区大小默认值是8kb,none是关闭缓冲区,sizekb是自己设置大小.
-autoFlush="true | false"
是否刷新缓冲区,true(缺省值)输出正常,false这个buffer溢出,就会导致一个错误,buffer设置为none,就要把这个设置为false.
-isThreadSafe="true | false"
设置Jsp文件是否能多线程使用。缺省值是true.
-info="text"
就是JSP的一些信息,能够使用Servlet.getServletInfo方法取回.
-errorPage="relativeURL"
指定接收Exception对象的JSP页面的URL.
-isErrorPage="true | false"
设置是否接收一个Exception对象.
-contentType="text/html;charset=ISO-8859-1"
设置页面类型和字符集.缺省类型是:text/html,缺省字符集为 ISO-8859-1.

JSP 汉字转拼音

<%...@ page language="java" import="java.util.*" contentType="text/html; charset=GBK" %>
<%...!
Hashtable ht=new Hashtable(10);
String g(Integer n){
int num=n.intValue();
if(num>0&&num<160){
return String.valueOf((char)num);
}
else if(num<-20319||num>-10247){
return "";
}
else{
if(ht.size()==0){b();}
while(!ht.containsKey(Integer.toString(num)))num--;
return ht.get(Integer.toString(num)).toString();
}
}
String c(String str){
char[] hz=str.toCharArray();
int len=str.length();
int p,q;
String ret="";
for(int i=0;i p=(int)hz[i];
if(p>160){
q=(int)hz[++i];
p=p*256+q-65536;
}
ret+=g(new Integer(p));
ret=ret+""+String.valueOf(p)+"
";
}
return ret;
}
void b(){
ht.put("-20319","a");
ht.put("-20317","ai");
ht.put("-20304","an");
ht.put("-20295","ang");
ht.put("-20292","ao");
ht.put("-20283","ba");
ht.put("-20265","bai");
ht.put("-20257","ban");
ht.put("-20242","bang");
ht.put("-20230","bao");
ht.put("-20051","bei");
ht.put("-20036","ben");
ht.put("-20032","beng");
ht.put("-20026","bi");
ht.put("-20002","bian");
ht.put("-19990","biao");
ht.put("-19986","bie");
ht.put("-19982","bin");
ht.put("-19976","bing");
ht.put("-19805","bo");
ht.put("-19784","bu");
ht.put("-19775","ca");
ht.put("-19774","cai");
ht.put("-19763","can");
ht.put("-19756","cang");
ht.put("-19751","cao");
ht.put("-19746","ce");
ht.put("-19741","ceng");
ht.put("-19739","cha");
ht.put("-19728","chai");
ht.put("-19725","chan");
ht.put("-19715","chang");
ht.put("-19540","chao");
ht.put("-19531","che");
ht.put("-19525","chen");
ht.put("-19515","cheng");
ht.put("-19500","chi");
ht.put("-19484","chong");
ht.put("-19479","chou");
ht.put("-19467","chu");
ht.put("-19289","chuai");
ht.put("-19288","chuan");
ht.put("-19281","chuang");
ht.put("-19275","chui");
ht.put("-19270","chun");
ht.put("-19263","chuo");
ht.put("-19261","ci");
ht.put("-19249","cong");
ht.put("-19243","cou");
ht.put("-19242","cu");
ht.put("-19238","cuan");
ht.put("-19235","cui");
ht.put("-19227","cun");
ht.put("-19224","cuo");
ht.put("-19218","da");
ht.put("-19212","dai");
ht.put("-19038","dan");
ht.put("-19023","dang");
ht.put("-19018","dao");
ht.put("-19006","de");
ht.put("-19003","deng");
ht.put("-18996","di");
ht.put("-18977","dian");
ht.put("-18961","diao");
ht.put("-18952","die");
ht.put("-18783","ding");
ht.put("-18774","diu");
ht.put("-18773","dong");
ht.put("-18763","dou");
ht.put("-18756","du");
ht.put("-18741","duan");
ht.put("-18735","dui");
ht.put("-18731","dun");
ht.put("-18722","duo");
ht.put("-18710","e");
ht.put("-18697","en");
ht.put("-18696","er");
ht.put("-18526","fa");
ht.put("-18518","fan");
ht.put("-18501","fang");
ht.put("-18490","fei");
ht.put("-18478","fen");
ht.put("-18463","feng");
ht.put("-18448","fo");
ht.put("-18447","fou");
ht.put("-18446","fu");
ht.put("-18239","ga");
ht.put("-18237","gai");
ht.put("-18231","gan");
ht.put("-18220","gang");
ht.put("-18211","gao");
ht.put("-18201","ge");
ht.put("-18184","gei");
ht.put("-18183","gen");
ht.put("-18181","geng");
ht.put("-18012","gong");
ht.put("-17997","gou");
ht.put("-17988","gu");
ht.put("-17970","gua");
ht.put("-17964","guai");
ht.put("-17961","guan");
ht.put("-17950","guang");
ht.put("-17947","gui");
ht.put("-17931","gun");
ht.put("-17928","guo");
ht.put("-17922","ha");
ht.put("-17759","hai");
ht.put("-17752","han");
ht.put("-17733","hang");
ht.put("-17730","hao");
ht.put("-17721","he");
ht.put("-17703","hei");
ht.put("-17701","hen");
ht.put("-17697","heng");
ht.put("-17692","hong");
ht.put("-17683","hou");
ht.put("-17676","hu");
ht.put("-17496","hua");
ht.put("-17487","huai");
ht.put("-17482","huan");
ht.put("-17468","huang");
ht.put("-17454","hui");
ht.put("-17433","hun");
ht.put("-17427","huo");
ht.put("-17417","ji");
ht.put("-17202","jia");
ht.put("-17185","jian");
ht.put("-16983","jiang");
ht.put("-16970","jiao");
ht.put("-16942","jie");
ht.put("-16915","jin");
ht.put("-16733","jing");
ht.put("-16708","jiong");
ht.put("-16706","jiu");
ht.put("-16689","ju");
ht.put("-16664","juan");
ht.put("-16657","jue");
ht.put("-16647","jun");
ht.put("-16474","ka");
ht.put("-16470","kai");
ht.put("-16465","kan");
ht.put("-16459","kang");
ht.put("-16452","kao");
ht.put("-16448","ke");
ht.put("-16433","ken");
ht.put("-16429","keng");
ht.put("-16427","kong");
ht.put("-16423","kou");
ht.put("-16419","ku");
ht.put("-16412","kua");
ht.put("-16407","kuai");
ht.put("-16403","kuan");
ht.put("-16401","kuang");
ht.put("-16393","kui");
ht.put("-16220","kun");
ht.put("-16216","kuo");
ht.put("-16212","la");
ht.put("-16205","lai");
ht.put("-16202","lan");
ht.put("-16187","lang");
ht.put("-16180","lao");
ht.put("-16171","le");
ht.put("-16169","lei");
ht.put("-16158","leng");
ht.put("-16155","li");
ht.put("-15959","lia");
ht.put("-15958","lian");
ht.put("-15944","liang");
ht.put("-15933","liao");
ht.put("-15920","lie");
ht.put("-15915","lin");
ht.put("-15903","ling");
ht.put("-15889","liu");
ht.put("-15878","long");
ht.put("-15707","lou");
ht.put("-15701","lu");
ht.put("-15681","lv");
ht.put("-15667","luan");
ht.put("-15661","lue");
ht.put("-15659","lun");
ht.put("-15652","luo");
ht.put("-15640","ma");
ht.put("-15631","mai");
ht.put("-15625","man");
ht.put("-15454","mang");
ht.put("-15448","mao");
ht.put("-15436","me");
ht.put("-15435","mei");
ht.put("-15419","men");
ht.put("-15416","meng");
ht.put("-15408","mi");
ht.put("-15394","mian");
ht.put("-15385","miao");
ht.put("-15377","mie");
ht.put("-15375","min");
ht.put("-15369","ming");
ht.put("-15363","miu");
ht.put("-15362","mo");
ht.put("-15183","mou");
ht.put("-15180","mu");
ht.put("-15165","na");
ht.put("-15158","nai");
ht.put("-15153","nan");
ht.put("-15150","nang");
ht.put("-15149","nao");
ht.put("-15144","ne");
ht.put("-15143","nei");
ht.put("-15141","nen");
ht.put("-15140","neng");
ht.put("-15139","ni");
ht.put("-15128","nian");
ht.put("-15121","niang");
ht.put("-15119","niao");
ht.put("-15117","nie");
ht.put("-15110","nin");
ht.put("-15109","ning");
ht.put("-14941","niu");
ht.put("-14937","nong");
ht.put("-14933","nu");
ht.put("-14930","nv");
ht.put("-14929","nuan");
ht.put("-14928","nue");
ht.put("-14926","nuo");
ht.put("-14922","o");
ht.put("-14921","ou");
ht.put("-14914","pa");
ht.put("-14908","pai");
ht.put("-14902","pan");
ht.put("-14894","pang");
ht.put("-14889","pao");
ht.put("-14882","pei");
ht.put("-14873","pen");
ht.put("-14871","peng");
ht.put("-14857","pi");
ht.put("-14678","pian");
ht.put("-14674","piao");
ht.put("-14670","pie");
ht.put("-14668","pin");
ht.put("-14663","ping");
ht.put("-14654","po");
ht.put("-14645","pu");
ht.put("-14630","qi");
ht.put("-14594","qia");
ht.put("-14429","qian");
ht.put("-14407","qiang");
ht.put("-14399","qiao");
ht.put("-14384","qie");
ht.put("-14379","qin");
ht.put("-14368","qing");
ht.put("-14355","qiong");
ht.put("-14353","qiu");
ht.put("-14345","qu");
ht.put("-14170","quan");
ht.put("-14159","que");
ht.put("-14151","qun");
ht.put("-14149","ran");
ht.put("-14145","rang");
ht.put("-14140","rao");
ht.put("-14137","re");
ht.put("-14135","ren");
ht.put("-14125","reng");
ht.put("-14123","ri");
ht.put("-14122","rong");
ht.put("-14112","rou");
ht.put("-14109","ru");
ht.put("-14099","ruan");
ht.put("-14097","rui");
ht.put("-14094","run");
ht.put("-14092","ruo");
ht.put("-14090","sa");
ht.put("-14087","sai");
ht.put("-14083","san");
ht.put("-13917","sang");
ht.put("-13914","sao");
ht.put("-13910","se");
ht.put("-13907","sen");
ht.put("-13906","seng");
ht.put("-13905","sha");
ht.put("-13896","shai");
ht.put("-13894","shan");
ht.put("-13878","shang");
ht.put("-13870","shao");
ht.put("-13859","she");
ht.put("-13847","shen");
ht.put("-13831","sheng");
ht.put("-13658","shi");
ht.put("-13611","shou");
ht.put("-13601","shu");
ht.put("-13406","shua");
ht.put("-13404","shuai");
ht.put("-13400","shuan");
ht.put("-13398","shuang");
ht.put("-13395","shui");
ht.put("-13391","shun");
ht.put("-13387","shuo");
ht.put("-13383","si");
ht.put("-13367","song");
ht.put("-13359","sou");
ht.put("-13356","su");
ht.put("-13343","suan");
ht.put("-13340","sui");
ht.put("-13329","sun");
ht.put("-13326","suo");
ht.put("-13318","ta");
ht.put("-13147","tai");
ht.put("-13138","tan");
ht.put("-13120","tang");
ht.put("-13107","tao");
ht.put("-13096","te");
ht.put("-13095","teng");
ht.put("-13091","ti");
ht.put("-13076","tian");
ht.put("-13068","tiao");
ht.put("-13063","tie");
ht.put("-13060","ting");
ht.put("-12888","tong");
ht.put("-12875","tou");
ht.put("-12871","tu");
ht.put("-12860","tuan");
ht.put("-12858","tui");
ht.put("-12852","tun");
ht.put("-12849","tuo");
ht.put("-12838","wa");
ht.put("-12831","wai");
ht.put("-12829","wan");
ht.put("-12812","wang");
ht.put("-12802","wei");
ht.put("-12607","wen");
ht.put("-12597","weng");
ht.put("-12594","wo");
ht.put("-12585","wu");
ht.put("-12556","xi");
ht.put("-12359","xia");
ht.put("-12346","xian");
ht.put("-12320","xiang");
ht.put("-12300","xiao");
ht.put("-12120","xie");
ht.put("-12099","xin");
ht.put("-12089","xing");
ht.put("-12074","xiong");
ht.put("-12067","xiu");
ht.put("-12058","xu");
ht.put("-12039","xuan");
ht.put("-11867","xue");
ht.put("-11861","xun");
ht.put("-11847","ya");
ht.put("-11831","yan");
ht.put("-11798","yang");
ht.put("-11781","yao");
ht.put("-11604","ye");
ht.put("-11589","yi");
ht.put("-11536","yin");
ht.put("-11358","ying");
ht.put("-11340","yo");
ht.put("-11339","yong");
ht.put("-11324","you");
ht.put("-11303","yu");
ht.put("-11097","yuan");
ht.put("-11077","yue");
ht.put("-11067","yun");
ht.put("-11055","za");
ht.put("-11052","zai");
ht.put("-11045","zan");
ht.put("-11041","zang");
ht.put("-11038","zao");
ht.put("-11024","ze");
ht.put("-11020","zei");
ht.put("-11019","zen");
ht.put("-11018","zeng");
ht.put("-11014","zha");
ht.put("-10838","zhai");
ht.put("-10832","zhan");
ht.put("-10815","zhang");
ht.put("-10800","zhao");
ht.put("-10790","zhe");
ht.put("-10780","zhen");
ht.put("-10764","zheng");
ht.put("-10587","zhi");
ht.put("-10544","zhong");
ht.put("-10533","zhou");
ht.put("-10519","zhu");
ht.put("-10331","zhua");
ht.put("-10329","zhuai");
ht.put("-10328","zhuan");
ht.put("-10322","zhuang");
ht.put("-10315","zhui");
ht.put("-10309","zhun");
ht.put("-10307","zhuo");
ht.put("-10296","zi");
ht.put("-10281","zong");
ht.put("-10274","zou");
ht.put("-10270","zu");
ht.put("-10262","zuan");
ht.put("-10260","zui");
ht.put("-10256","zun");
ht.put("-10254","zuo");
ht.put("-10247","zz");
}
%>
<%...
if(request.getParameter("hz")!=null)
{
out.println(c(request.getParameter("hz")));
}
%>

请在此处输入中文:


输入出结果格式是这样的:

如:我输入“请在此处输入中文”

输出结果为:

qing-14357
zai-11046
ci-19253
chu-19290
shu-13596
ru-14101
zhong-10544
wen-12604

关面是拼音 ,后面是算出来的代号(为什么得到这样的数字,我也不知道),如果有时汉字不常用,没有加入,就只会显示出来代号,而不显示拼音,此时,你可以将其加入到里面就行了,格式如:ht.put("-10247","zz");