发新话题
打印

[技术] [教程+分享]具有良好体验度的Web注册系统

[教程+分享]具有良好体验度的Web注册系统

引用:
*项目名称:具有良好体验度的Web注册系统
' u0 J' B7 ^+ P) Q4 q*作者:草履虫
$ Q3 @/ {4 i8 X, f7 z*联系:caolvchong@gmail.com% V7 f) b- V1 Q8 |& `0 E
*时间:2007-6-29
. C( Q+ l) J( S*起因和版权说明:" n# R* |& N' X& `6 I! O
  1.草根上有位会员发布了个类似的系统,提问说验证码不支持firefox的刷新,于是萌生念头做一个.本系统外观(按钮取色等)借鉴了该系统,但细节实现原理并不相同(该文地址:http://bbs.blueidea.com/thread-2761325-1-4.html).9 F0 X) N3 u7 w2 C- j1 ]
  2.另外,自己做的这个注册系统中利用了网络上的无组件验证码(作者sipo)7 h. m- z$ G( {0 b- e1 |$ M. l
  3.至于密码强度的算法借鉴了草根的一篇文章(
http://www.blueidea.com/tech/web/2006/4324.asp),但该算法并不十分理想,如果有更好算法的朋友不凡交流一下7 j# j, h# S! F+ R8 l
*特点和知识点:5 N0 ?# @2 E5 Z, J" D
  1.AJAX验证用户名和验证码,同时异步进行用户名注册(都属于AJAX的很基础部分)
' z1 H1 s) J, ~5 S" c+ B, d  2.支持验证码刷新(包括firefox平台下)
& r; O  O8 d, o: u  3.密码,邮箱,用户名等即时检测(利用javascript DOM)
; r& t3 G0 a6 j2 b2 D  4.HTML通过W3C Strict验证,CSS也通过W3C CSS验证(其实这个有点多余,并不完全必要)

7 z9 U% u. v* {*开发平台:Windows2003 IIS6.0 Access数据库, A* G& [7 o- X' N- ^' q: e! y
*工具: DreamWeaver(写ASP),Aptana(写Javascript,HTML和CSS),Emeditor(写这篇文章),Access2003(数据库)- x8 _! X1 }( X8 ?* y; e
*测试平台:Firefox2.0,Opera9.21,IE6.0,IE7.0
5 I& R# _# @! v- x+ }& p8 b* ~*演示地址:http://finish.3322.org/reg/reg.htm(短期有效,在本机上,可能访问不顺畅)
0 k1 H1 g" X4 W2 V, j' j1 ^*原文地址:http://cceer.xmu.edu.cn/blog/view.asp?id=521 R8 }5 H  n  u* X" Q
*补充:& J# B4 j$ i7 ?- v! `1 X) |: c$ I
  如果你使用这个注册系统,请务必注意下列问题:
. z! ~; Q8 {1 ^% r- R/ d6 \/ i: e    本系统没有对密码进行加密,如果需要,可以搜索MD5加密! ?9 \6 c1 |' O* r1 `% X3 a9 I
    本系统没有进行防注入设置,如果需要,可以搜索SQL防注入9 f+ X; `5 i  n- S) x
  限于本人水平上的限制,错误和不足在所难免,如果你有问题或者建议,请联系我,感谢!
9 j4 D8 C$ g, j; d+ p, i7 N& M*这里是效果图
6 W) R: J5 Z# c6 S
/ _1 ]4 o$ N* [( ?
这里是所有文件的打包下载(包括所有文件,图片,数据库等,解压后请在IIS下测试)
& B8 K+ L& b5 \7 F0 n2 p0 V, H( g' P

  s0 u6 T$ i; A1 g( G4 N2 l* \# A限于文章长度的限制,只帖出两个js文件和一个显示注册页面,至于后台处理页面以及css文件等,请在压缩包中查看
- _9 R5 U$ d7 d! \& k
引用:
8 Z+ D+ S' u8 ?( r0 g6 N( E
注册页面reg.htm4 L2 e7 |; A1 w! U7 P3 C
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
& f) R" C8 d0 i4 {1 f<html xmlns="http://www.w3.org/1999/xhtml" lang="gb2312">
: l. O& Q' a" I+ N8 z  <head>
- y! h9 R7 ]' \/ Z& f    <meta http-equiv="Content-Type" c />
0 j- D, O6 }* k  {9 l! j    <title>草履虫---简易AJAX注册页面</title>0 u  n, b( I* H, v( d) E
<link href="reg.css" type="text/css" rel="stylesheet" />. t( w" J0 d0 U8 B8 }$ }
<script src="detect.js" type="text/javascript"></script>- O" x  @; D' V! g$ c5 K0 |+ _
<script src="ajax.js" type="text/javascript"></script>
  J8 W0 k0 U* {6 t4 O  </head>
0 J( ^" P7 A. J. D2 K) f$ e( w: _  <body >5 n+ J# q+ k$ k: m- `" E
   <ul>
3 x! }/ ~# T: d* g2 o+ K  <li id="title">草履虫---Web注册系统</li>
: {  G" S$ o* E  B1 C* ^! X  <li class="underline">' ?; T6 Z( `9 l3 [0 r5 G1 C: @& K
   <label>注册用户名:
$ V' Q/ q/ G/ B) s, g9 @    <input type="text" maxlength="16" />
. C- \7 E3 F$ a- _   </label>
' u( m) }# Y' q8 D9 f3 ^  _; Q   <span>支持汉字,单词,数字,敏感字符屏蔽</span>
: t5 S( `& _3 A  </li>- [& ]4 Z9 X2 q/ u
  <li>
' S: X2 D; |# O: F, `   <label>注册密码:; s1 x& b+ \- ~( a0 b# o# O' X4 a
    <input type="password"  />
/ J# N9 e0 M9 A* X   </label>
' l  r& U3 b7 F: y( ?9 P' x8 S/ K   <span>密码在6-16位之间,敏感字符屏蔽</span>2 Q% s5 l# l6 u/ j
  </li>) f4 U( m: s6 |
  <li class="underline">
7 Z0 Y! a# y7 w, q* H   <label>重复密码:
! P7 J; F- m- G1 b, e5 f8 J4 q# z    <input type="password" maxlength="16" />
7 {0 J! l6 h" N# w# t3 r7 ]   </label>, X. b8 `+ B: Y, \3 ?
   <span></span>7 E3 n/ i9 L' c
  </li>- X# \1 U9 m4 X5 l8 V
  <li class="underline">5 `7 C! o% t& b! \; j& M
   <label>邮箱:" z: @# C3 U; r# C
    <input type="text" />; i% U2 d* ^# X6 m! j
   </label>- n9 k1 Q& E) k) V
   <span>email是联系重要手段</span>; i4 ~' Q/ c2 A8 T! R+ O
  </li>
2 B! n- R  z/ t- t0 t. A% U  <li class="underline">验证码:0 p" E& ]2 P+ T- o6 Y1 l/ k
   <input type="text" maxlength="5" />7 o- |- w  y9 G
   <label>
; C$ C, \$ k$ W* f# q0 h% x; a) O8 J    <img src="getcode.asp" id="src" height="18" alt="看不清楚?请点击刷新" />% u% W( M9 I$ y9 @# z0 Y
    <span>看不清楚?请点击验证码刷新</span>0 M# d7 Q2 F1 t: [$ ]  D1 y+ T
   </label>
7 @& j" [# R+ `2 f# ?! X! h  </li>
( Q+ e& ?- U; ^( f  <li class="underline">& j8 m/ Z) X3 q5 {8 p; d
   相关协议:7 w  I4 ?; D$ v! R
    <label ><input type="radio" name="info"/>接受</label>
2 o3 Y0 t6 G0 y# A& y' E; p4 f    <label ><input type="radio" name="info"/>不接受</label> ; b: t) n$ H% S6 i. W, d* `% q
    <input type="button" value="阅读协议" class="button" />0 {5 _: q; L- K) c
  </li>" N0 H& `3 z9 W% I
  <li class="underline">4 \' |* _2 W  ~* ]* J
   <input type="submit" value="注册" class="button setleft" />
5 K7 q4 z# {/ |9 i( Y   <input type="reset" value="重置" class="button"  />
/ P: }5 P8 t1 I" ~   <span></span>" E0 Z. M; D3 m  H% ^$ v# v- c3 ~
  </li>. z- H) l' ]- f4 }0 E1 T  {$ O
  <li class="copyright">作者:草履虫</li>" t4 |7 E# [) e% e" V8 M
  <li class="copyright">时间:2007-6-28</li>* J. [! A2 a3 W# d3 {
  <li class="copyright">联系:caolvchong@gmail.com</li># X) A% d3 Z3 B& b2 V! c6 `- D, @
  <li class="copyright">Blog---Web2.0之路:<a href="[url=http://cceer.xmu.edu.cn/blog/%22%3Ehttp://cceer.xmu.edu.cn/blog/%3C/a%3E%3C/li]http://cceer.xmu.edu.cn/blog/">http://cceer.xmu.edu.cn/blog/&lt;;/a></li[/url]>
1 @; ^" N" z1 p$ U" e+ m</ul>
4 Z# v2 z- S( c4 E7 Z  </body>5 f0 O+ }6 |+ o0 w3 _
</html>
% R. p, O& T& W4 F) W1 Y
5 w$ q% M3 k1 P) W" C2.数据合法性检测detect.js4 |' d  u/ A9 w

! k  t7 o7 @: |* q# H2 ]2 ]
引用:
4 E) P( V% z" h$ [! |( C  {
var flag=[0,0,0,0,0,0];
4 V5 M8 V: T; H& I7 V  var $=function(tagName){
9 y: K% L% ]. y6 s7 y3 S7 [   return document.getElementsByTagName(tagName);
; z% p$ T/ k' b! ^3 @" R  }- U* b6 H8 x; g/ l
//----------接受协议
- i; _6 f% t4 r: Z0 f) H( U  function accept_info(){% }0 B. g/ I! I, f& w
   flag[0]=1;( o9 B+ y- e5 t2 W
   check_data();$ F+ {/ q$ \" X( u% o5 K  T0 @. L
  }
# c6 Q# W1 G2 }7 q! j& H+ I//----------拒绝协议2 V) P% E" l, ^9 E# O5 k8 R9 _
  function refuse_info(){
% f  o% L+ k3 i   flag[0]=0;. v  K6 q, b! \3 c( ~1 c- x
   check_data();
  j+ H! w5 f* r- R% I2 |4 O8 C5 ~, J3 q  }# q7 L% Q+ U! d
//----------重置8 D$ p. t# ?% y/ ?5 l" v$ @$ @
  function reset_info(){8 G4 G) `3 `* F2 J7 j/ m6 k! @: p
   var info=["支持汉字,单词,数字,敏感字符屏蔽","密码在6-16位之间,敏感字符屏蔽","","email是联系重要手段","看不清楚?请点击验证码刷新"]& i5 \7 \& _' @9 E  `3 F  [
   for(var i=0;i<$("span").length;i++){
4 a( ]+ ?/ `8 g    $("span").innerHTML=info;
3 s& `0 Y0 T* F: R" w4 {1 C. K    flag=0;3 _9 C* q9 G# Z" k# y/ ]
   }8 D: K; ]5 k- }* x- L% }) [
   for(var i=0;i<$("input").length-3;i++){. x9 |7 `2 C# e# i
    $("input").value="";$ j7 y& ]' \! S' M& [; w* x  g' s+ E
   }2 D9 X) L1 M, R; s
   check_data();
& e2 |3 f' w1 N; ^5 \* g: J  }* _' O8 c& \# ?! H
//----------邮箱检测9 I* @, C5 k; R# n
  function check_email(email){
  G0 B; @% o6 a4 t. h   var reEmail=/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;- L* d' v' [* e) |5 _# I
   var b_email=reEmail.test(email);9 X7 Y- Q) \% x# k6 G  z; s
   if(b_email){
5 |! K* \+ t$ N0 _$ z    $("span")[3].innerHTML="<img src='yesok.gif'/> 邮箱可用";
' ^. m8 R+ `2 B4 n    flag[1]=1;. C( U2 W" R4 K0 L
    check_data();
" F. E+ X) _5 p2 v" b& E   }
& K# s$ E6 `' V   else{$ @+ j$ G7 |$ H6 N4 }! g; F
    $("span")[3].innerHTML="<img src='yesno.gif'/> 邮箱错误";8 F3 ~2 H8 k( E3 w+ G
    flag[1]=0;
: g7 }5 `$ f( q, c9 v  y8 G4 w8 s    check_data();" {7 |# R3 T" N2 |, y' y8 C
   }
5 `9 ^" e7 K: T5 F  }
* P- X' c. `+ }//----------密码检测
3 s2 b$ Z* q/ K* Q( ^  function check_password(obj){3 K3 L! H( E% N% U
   var pwd=$("input")[1].value;6 w1 ]0 ~7 P! [& E+ |
   var reChinese=/[\u0391-\uFFE5]+/;% q% q& m" _/ }& @4 w% S
   var b_chinese=reChinese.test(pwd);$ b- ^; t% t7 U; m( o
   var reSpace=/\s+/;0 Q1 G; T+ s" ]9 Q" P: F# e  w3 }
   var b_space=reSpace.test(pwd);
# d; z9 |! c, m5 Y9 `4 N& |   //-------长度测试
" {7 q( v; M* i  L' S' P- Z   if(pwd.length<6){( o8 \, E" I( L" ~
    $("span")[1].innerHTML="<img src='yesno.gif'/> 密码长度不能小于6";
* d& F) x, N1 @4 _    flag[2]=0;
, t8 X2 |; A' R- c& @, b2 |0 g    check_data();, T8 e- ?  R2 N. ]
   }8 z+ Z+ `# n: w, K
   //-------合法性检测:不能包含汉字
# z$ A& h; e2 q) e* k$ |1 U   else if(b_chinese){9 N/ O' u9 t0 p5 h: D
    $("span")[1].innerHTML="<img src='yesno.gif'/> 密码不能包含中文";
) g( a) d" s, ~0 O/ Y    flag[2]=0;
+ l' v9 t% j/ }& q, C    check_data();
, T2 e: _4 ~0 @# \& m9 m   }; d0 z/ g0 V/ ~4 G8 a
   //-------合法性检测:不能包含空格
7 n, i* S( j1 k6 q$ R+ L   else if(b_space){# e3 q- t  J. C3 K- ~( z. |+ z$ H
    $("span")[1].innerHTML="<img src='yesno.gif'/> 密码不能包含空格";1 p% J0 [: N) Z$ W" S! T
    flag[2]=0;
2 _9 p: C3 O' f    check_data();7 D4 r' `+ r* F
   }- G6 b2 R1 o& L
   //-------合法时显示密码强度1 g/ O$ a0 v) e$ b; N, O
   else{& u6 ?) h) k7 P* [: E
    //定义对应的消息提示
, J, ~- `# w/ n    var num=getResult(pwd);
( a8 i% c6 U# E2 T    var msg=new Array("<img src='bad.gif'/> 密码强度差","<img src='comm.gif'/> 密码强度一般","<img src='good.gif'/> 密码强度强壮");1 Z! u# g# J- X: H- t* D2 t0 D
    $("span")[1].innerHTML=msg[num];2 P7 k0 w( j5 n( A
    if($("input")[2].value!=""){' d0 |3 o5 l4 |
     check_pw();7 q$ G. R8 J# p- j
     }
% k% d) b" U- T. J9 P, a    return flag[2]=1;# K1 r5 E/ ~9 J$ C3 v. N$ }
    check_data();
$ h# i8 h9 Q; {    }3 F& y, P. c6 n, ^
   }
: K+ x, q8 ]1 S4 K   //定义检测函数,返回0/1/2分别代表差/一般/强
+ o2 \, I$ }& z   function getResult(s){
+ ^: e' E  @& ]! p    var ls =-1;2 I. q" S( G* I  K/ _
    if (s.match(/[a-z]/ig)){
9 g1 F1 A3 e( c7 O) U( \     ls++;7 N* o: ?8 _+ ?4 s& I- S4 z
    }% h5 w) F5 E( E$ H7 }; R: ^
    if (s.match(/[0-9]/ig)){
) Z& ]! s' l" M     ls++;) ~- J! u1 x5 f. i
    }: ?9 N$ Z$ \# s# [6 l" ~
     if (s.match(/(.[^a-z0-9])/ig)){
9 ?8 h( q' o+ f0 B! _! P" x     ls++;
, b  s' q2 l6 |; o) W    }4 s: T) c8 l$ |; U5 {0 H7 i5 I
    return ls;0 W6 k7 C( y; r3 C
   }
+ K$ [. J' d$ O+ {4 A5 z1 X  //---------密码一致性检测
; ?/ ?$ c8 t# Q) [   function check_pw(){
+ S" F' I& ?5 ?8 a6 s    var pwd=$("input")[1].value.toString();' y7 H) ?) Q5 L. Q
    var check_pwd=$("input")[2].value.toString();2 \# R5 m6 H9 \6 c1 z
    if(flag[2]==1){! o! ~- L9 S3 g: K: s+ n, h
     if(pwd==check_pwd){
+ C% X) p, X2 D1 R      $("span")[2].innerHTML="<img src='yesok.gif'/> 密码可以使用";$ X' Z- B5 s+ ~. L4 i: l, g
      flag[3]=1;
  M: W" f0 a8 r" B7 n- r# w      check_data();
. G% {, {1 `2 j0 w; c$ b     }
2 N0 f# M( H1 R6 J: J7 J     else{
0 L6 a: M- j5 L* A& [: M      $("span")[2].innerHTML="<img src='yesno.gif'/> 两次密码不相同";; Q2 \" @* k0 q' Z
      flag[3]=0;0 I+ }8 H9 p9 z4 z
      check_data();
0 `% O5 V, k+ V1 l     }5 ?& h$ S) n* Y0 `2 \. A
    }; L0 S' c* W! i4 O/ d- \( s
   }4 c& M, \% q2 K/ ]& Y
  //---------用户名合法性检测7 E& h# Q1 j5 `0 U, t# f9 [
   function check_id(id_name){//只能字母和数字,是否相同用AJAX判断: W& J. _, J1 \* H+ }, F4 }/ I* A
    var reId=/^[\w\u0391-\uFFE5]+$/;* B$ c; w, S4 @7 W9 h
    var b_id=reId.test(id_name);3 y- O  s$ H/ p8 ?) R& o1 Z
    if(!b_id){( ~% @. J0 d: l
     $("span")[0].innerHTML="<img src='yesno.gif'/> ID命名非法";8 Y4 B+ T, E8 e. h  C
     flag[4]=0;( ^* x4 S! U1 f6 b: O) [8 ]
     check_data();5 i6 F% }$ `6 T$ s9 n2 q! @9 ]
    }
9 h% `' \' j4 a# u* C2 f5 l3 C) @3 b    else{//合法用户名用ajax的checkid()检测是否被注册过/ C( L6 B, Y1 j4 k+ F# B" ?
     checkid(id_name);) h) `$ w. ~2 \+ Z; P
    }. m0 u$ d8 ]: p2 y5 u+ p
   }0 s/ r- [8 q- {  k
  //---------检查数据,使提交按钮是否生效
9 ?4 g5 z: L# h. ^: X, H) K   function check_data(){6 ^/ G7 `7 Q) @- m, O
    if(flag[0]==1 && flag[1]==1 && flag[2]==1 && flag[3]==1 && flag[4]==1 && flag[5]==1){( m$ b$ ^, f/ Q$ i/ z
     $("input")[8].disabled=false;
; z1 Y# P, E  U9 p    }" Z7 S3 _9 Z% {7 ]
    else{
5 ^# B# @; s. N3 r     $("input")[8].disabled=true;  B0 k' S3 c2 W
    }8 @" f$ A5 L5 r2 C; y$ ~5 h
   }8 s% E, l* b( K% v. |; Q5 J) _
   
5 f9 x1 W! Y; s$ @! ^9 N9 H//--------------------------------------------------------------------7 i/ U5 U  L: H2 V
- s) M3 W$ n* o) K

# a3 v8 M# @' U' J# B3 f
; j$ h: l7 l  u& x7 \& d. g' v' |$ P

TOP

3.关于ajax数据交互ajax.js
复制内容到剪贴板
代码:

function checkcode(regcode){
var xmlhttp;
try{
  xmlhttp=new XMLHttpRequest();
  }
catch(e){
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4){
  if (xmlhttp.status==200){
   var data=xmlhttp.responseText;
   code_result(data);
   }
  else{
   $("span")[4].innerHTML="验证码校验失败,请联系管理员";
   }
  }
else{
  $("span")[4].innerHTML="正在进行验证码校验...";
  }
}
xmlhttp.open("post", "check_code.asp", true);
xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlhttp.send("regcode="+escape(regcode));
}
function code_result(data){
var resultbox=$("span")[4];
if(data==1){
  resultbox.innerHTML='<img src="yesok.gif"/> 验证码正确';
  flag[5]=1;
  check_data();
  }
else{
  resultbox.innerHTML='<img src="yesno.gif"/> 验证码错误';
  flag[5]=0;
  check_data();
  }
}

//--------------------------------------------------------------------
function checkid(regid){
var xmlhttp;
try{
  xmlhttp=new XMLHttpRequest();
  }
catch(e){
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4){
  if (xmlhttp.status==200){
   var data=xmlhttp.responseText;
   id_result(data);
   }
  else{
   $("span")[0].innerHTML="用户名检测失败,请联系管理员";
   }
  }
else{
  $("span")[0].innerHTML="正在进行用户名校验...";
  }
}
xmlhttp.open("post", "check_id.asp", true);
xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlhttp.send("regid="+escape(regid));
}
function id_result(data){
var resultbox=$("span")[0];
if(data==1){
  resultbox.innerHTML='<img src="yesok.gif"/> 用户名可用';
  flag[4]=1;
  check_data();
  }
else{
  resultbox.innerHTML='<img src="yesno.gif"/> 该用户名已经被注册';
  flag[4]=0;
  check_data();
}
}
//--------------------------------------------------------------------
function sendinfo(regname,pwd,email){
var xmlhttp;
try{
  xmlhttp=new XMLHttpRequest();
  }
catch(e){
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4){
  if (xmlhttp.status==200){
   var data=xmlhttp.responseText;
   reg_result(data);
   }
  else{
   $("span")[5].innerHTML="注册失败,请联系管理员";
   }
  }
else{
  $("span")[5].innerHTML="正在进行用户名注册...";
  }
}
xmlhttp.open("post", "reg.asp", true);
xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlhttp.send("regname="+escape(regname)+"&pwd="+escape(pwd)+"&email="+escape(email));
}
function reg_result(data){
if(data==1){
  $("span")[5].innerHTML='<a href="http://cceer.xmu.edu.cn/blog/" target="_blank">'+$("input")[0].value+",您好.请点击这里登陆</a>";
  }
else{
  $("span")[5].innerHTML="注册失败,请联系管理员";
}
}

TOP

这是什么 啊! c2 y) M: \' d. F! k

4 ^; ^& A% h6 l. s8 D
; N, H! p5 n" J% s. k* p. n1 x$ J+ n
( J; s+ {. i: P
' v0 G" b# f/ J% o
1 T! m% r: {! i0 W3 G0 n: ?
3 h- B/ b/ V$ ]

* z" _; a' B# _  _
* _% {6 _9 T& K4 V8 [- G% i5 Z3 X, ?0 ^% z% O1 I0 ]# H: Y
5 n" m7 y  ^2 M' f( M  q
9 X0 e  A( }7 d; D/ g6 K5 p
- R. G9 G) p* x" m
" w4 m9 d# P& M, O) U

1 `3 z1 j# C7 p/ Q; H. q  Y1 M
* G8 A9 G% I! V2 x0 ^& j8 n( I- L' M4 r. ^4 X7 a7 Q. t& S
$ @8 n, W! z+ ~* j

7 O+ Q* c& w0 L$ U/ F# k
: w" R# n. W3 T- k% P1 [7 J, X& A' N! _0 \
, s' G! m5 ~( ^+ s$ b2 N3 C/ l

# D0 d) J& z: w: b, u  o9 F不灭星辰诀

TOP

发新话题