1.HTML表单的提交方式
对于一个普通HTML表单来说,它有两个重要的属性:action 和 method。
action属性指明当前表单提交之后由哪个程序来处理,这个处理程序可以是任何动态网页或者 servlet 或者 CGI(Common Gateway Interface),在asp.net里面一般都是都aspx页面来处理。
method属性指明form表单的提交方式。它有两个可能值get和post。
(1)get方式提交的表单在地址栏会显示参数名和参数值,而post方式不会。用post提交参数相对来说更隐蔽一些,也相对安全一些。假如我们这个页面用于用户登录并且存放用户信息的表为“users”,我们的sql语句可能会这么写:
string sql=” select * from users where username='”+username+”’ and password='”+password+”’”;
然后我们的 username 和 password 变量从表单提交的数据获取,正常情况下用户填写是没有问题,就上面的例子来说用户填写的用户名和密码分别是“sa”和“123456”,那么我们最后得到的SQL语句是:
sql=”select * from users where username=’sa’ and password=’123456’”
这样是没有问题的。
如果用get方式提交,用户可以对上面的参数进行一些改动,比如在地址栏直接输入:
http://localhost/GetUserInfo.aspx?username=zhoufoxcn&pwd=123';delete * from users'
那么我们得到的SQL就是:
string sql=” select * from users where username='zhoufoxcn' and password='123';delete * from users'”
执行上面的SQL语句就能把Users这个表里的所有数据删除掉!这个一个触目惊心的危险!这个就叫SQL注入。
(2)由于浏览器地址栏能输入的最大字符数有限制,所以用get方式提交不能处理参数值更大的表单,而post方式则没有这个限制。
2.获取表单值
通过用get方式提交表单我们可以看到提交到服务器的时候,在网页后面有“?username=sa&pwd=12345”这么一个字符串,也就是以表单里HTML控件的名字=控件值的方式,并且如果存在多个控件,彼此之间以“&”分割,那么我们就可以以控件名来获取控件值。获取HTML控件值常见有以下集中方式:
获取方式 | 表单提交方式 |
Request.QueryString["控件名"] | 适合于get方式提交的表单 |
Request.Form["控件名"] | 适合于post方式提交的表单 |
Request["控件名"] | 同时适合于get和post方式提交的表单 |
3.乱码问题
对于用户登录的表单,我们在用户名和密码处分别输入“小姑凉”和“123456”,用户就可能会变成“???”,之所以出现这样的情况就是因为我们的编码原因。
所谓乱码,就是用一种编码的字符串却用了另一种编码来显示,造成不能正常显示的现象。
这就像我们在酒吧里对一个懂普通话的服务员说来一杯酒,他马上会送你一杯酒;可是当我们对一个不懂普通话的服务员用普通话说来一杯酒,他就会一头雾水了。
之所以出现乱码就是因为在这里客服端请求的编码和服务器响应的编码不一致
默认情况下 Request 的 ContentEncoding 为 UTF8Encoding ,而 Response 的 ContentEncoding 为 System.Text.DBCSCodePageEncoding ,二者的不一致导致了输入中文成了乱码。
我们常见的编码有 gb2312、gbk 和 unicode 几种,gb2312 能显示日常生活最常用的 6000 多个汉字,这对于一般的公文足够了,可是如果要用来显示一个古文献就不行了(据说康熙词典收录了4万多汉字),当它不能显示的时候也会出现乱码。
Gbk 是在 gb2312 的基础上扩展的,大概能显示1万8千多个汉字,这对于一般古文献也差不多够了。
Unicode 则更大一些,它能显示 20901 个汉字(范围是从/u4e00到/u9fa5),并且还能显示日文、韩文、台湾文字、香港文字和新加坡等文字,所以目前很多网站都采用unicode编码。Utf8编码就是unicode编码中的一种。
<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
更改为:
<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="utf-8" %>
这样就能正常显示了。
建网站的时候默认编码就是utf-8,无需更改。
4.服务器端表单
在此之前我们见到的表单都是如下格式:
<form action="接收数据页面" method="post">
并且我们都是利用的HTML控件。现在我们要介绍服务器端表单,服务器端表单与前面的表单相比,多了一个runat=”server”标记,如下:
<form id="form1" runat="server">
在服务器端表单里可以不用指定action属性,表示由当前页面处理,也可以不指定 method 属性,默认为post方式提交表单。在服务器端表单里,我们不光可以使用 HTML 控件,还可以使用 HTML 服务器控件,还可以使用 asp.net 控件 。
另外需要注意的是,在一个 asp.net 页面中可以有多个不带 runat=”server” 标记的表单,但是只能有一个服务器端表单。
5.HTML服务器控件
HTML服务器控件与普通服务器控件不同的是:在普通HTML控件中加上了一个 id 属性和一个 runat=”server” 标记。如下就是一个 HTML 服务器控件:
<input type="text" runat="server" id="txtUserName" />
HTML服务器控件有几个限制:
在整个 asp.net 页面中这个控件 id 的必须唯一,并且 HTML 服务器控件只能放在 HTML 服务器表单中。因为一个 asp.net 页面只能有一个服务器表单,所以说在服务器表单中控件的 id 值必须唯一,因为我们在编程的时候通过这个 id 来访问 HTML 服务器控件。如果不唯一就会报错。
所有的服务器控件经过服务器运行之后都会变成标准的 HTML 控件。
这样我们可以得出一个结论:如果我们的控件功能本来就很简单,我们就可以直接使用HTML控件,这样就可以减轻服务器的负担,提高运行效率。
另外,在上面的代码中多了一些以前我们没有见过的部分:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNTQ0MjI5MTUzZGR1mFZ52ODFgAKe7Qx9/67qMGFJCA==" /> <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWBAKIpeT6DgKl1bKzCQK1qbSRCwLdkpmPAcJ7Zy/C66ypRIq49nr3hQNayqwk" />
因为服务器会保存服务器控件的状态和属性,所以它会利用一些隐藏域来保存这方面的信息,这部分的内容是经过 Base64 编码的。
服务器控件的好处是我们可以动态在代码中动态控制服务器控件的属性。