- 浏览: 614237 次
- 性别:
- 来自: 卡哇伊
文章分类
- 全部博客 (299)
- C# (25)
- Java (1)
- WinForm (0)
- Asp.Net (86)
- Jsp (2)
- Php (1)
- Web Service (0)
- Desgin Patterns (19)
- Data Structure & Algorithms (1)
- SQLserver (41)
- Mysql (0)
- Oracle (2)
- Javascript (50)
- Ajax (10)
- Jquery (1)
- Flex (0)
- Regular Expression (5)
- DIV+CSS+XHTML+XML (18)
- Software Test (0)
- Linux (0)
- Utility (17)
- Net Digest (4)
- windows 2003 (10)
- Other (4)
- English (1)
- IT Term (1)
最新评论
-
w497480098h:
学习了 很好谢谢
SQL Server下无限多级别分类查询解决办法(简单查询树形结构数据库表) -
main_fun:
确实不错
iframe自适应高度 -
jveqi:
...
DBA -
mxcie:
其它版本没有确认,今天使用vs2003时,其.sln文件也需要 ...
彻底删除项目的VSS源代码管理信息 -
moneyprosper:
就只有IE支持,火狐和谷歌都不支持此种方法。正在寻找中。。。
从父页面读取和操作iframe中内容方法
在今天我主要要介绍的有如下知识点:
HTML表单的提交方式
HTM控件
获取HTML表单内容
乱码问题
SQL注入
服务器端表单
HTML服务器控件
HTML表单的提交方式
对于一个普通HTML表单来说,它有两个重要的属性:action和method。
action属性指明当前表单提交之后由哪个程序来处理,这个处理程序可以是任何动态网页或者servlet或者CGI(Common Gateway Interface),在asp.net里面一般都是都aspx页面来处理。
method属性指明form表单的提交方式。它有两个可能值get和post。
下面我们以一个例子来说明get和post的区别。用Dreamweaver8创建两个aspx页面,分别为Register.aspx和GetUserInfo.aspx。暂时我们不需要在GetUserInfo.aspx页面写任何代码,Register.aspx页面的代码如下:
<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>用户注册</title> </head> <body> <form action="GetUserInfo.aspx" method="get"> <table border="1" width="400px"> <tr><td colspan="2">用户注册</td></tr> <tr><td>用户名</td><td><input type="text" name="username" /></td></tr> <tr><td>密码</td><td><input type="password" name="pwd" /></td></tr> <tr><td><input type="submit" value="提交" /></td><td><input type="reset" value="重置" /></td></tr> </table> </form> </body> </html>
将Register.aspx和GetUserInfo.aspx都保存到C:\Inetpub\wwwroot下,然后打开浏览器在地址栏中输入http://localhost/register.aspx,用户名和密码分别输入“zhoufoxcn”和“123456”,点击“提交”按钮,我们看到如下结果:
注意上面的代码中“<form action="GetUserInfo.aspx" method="get">”这句,现在我们仅仅将method由“get”变成“post”,我们再次输入“zhoufoxcn”变成“123456”,提交表单,我们看到如下结果:
细心的朋友可能会注意到,当我们以get方式提交的时候,在浏览器地址栏里除了接收参数的网页名之外,还有我们的表单名和参数值,在这里是“username=zhoufoxcn&pwd=123456”,而以post方式提交的时候地址栏除了接收参数的网页之外并没有这样参数。具体说来get和post提交方式有如下两个区别:
(1)get方式提交的表单在地址栏会显示参数名和参数值,而post方式不会。用post提交参数相对来说更隐蔽一些,也相对安全一些。假如我们这个页面用于用户登录并且存放用户信息的表为“users”,我们的sql语句可能会这么写:string sql=” select * from users where username='”+username+”’ and password='”+password+”’”;然后我们的username和password变量从表单提交的数据获取,正常情况下用户填写是没有问题,就上面的例子来说用户填写的用户名和密码分别是“zhoufoxcn”和“123456”,那么我们最后得到的SQL语句是:sql=”select * from users where username=’zhoufoxcn’ 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方式则没有这个限制。
上面我说到用post方式提交表单相对安全,并没有说绝对安全,就拿上面的表单来说,假如上面的网站代码发布在www.netskycn.com上发布,我们可以通过http://www.netskycn.com/register.aspx和http://www.netskycn.com/GetUserInfo.aspx来访问,那么我们完全可以在本地制作一个网页,HTML的页面都行,它的代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>用户注册</title> </head> <body> <form action="http://www.netskycn.com/GetUserInfo.aspx" method="post"> <table border="1" width="400px"> <tr><td colspan="2">用户注册</td></tr> <tr><td>用户名</td><td><input type="text" name="username" value="zhoufoxcn" /></td></tr> <tr><td>密码</td><td><input type="password" name="pwd" value="123';delete * from users" /></td></tr> <tr><td><input type="submit" value="提交" /></td><td><input type="reset" value="重置" /></td></tr> </table> </form> </body> </html>
注意表单的action属性我用了全路径的url地址,只要我们能连上互联网,那么这个表单一样可以正确提交的,同样也能产生触目惊心的危害!对于这个问题如何避免我会专门抽出一篇文章来讲如何防范,这里暂不赘述。
HTML控件
HTML控件在上面的例子里已经用到,它就是指用HTML表单里的一些列元素来提供用户交互,它们都是类似“<input type=”text” name=”name””这样的标记。要呈现什么的形式由type属性来决定,可以有“text”、“password”、“radio”、“checkbox”、“submit”及“reset”等,分别呈现为文本框、密码框、单选框、复选框及提交按钮和重置按钮等。
获取表单值
通过用get方式提交表单我们可以看到提交到服务器的时候,在网页后面有“?username=zhoufoxcn&pwd=12345”这么一个字符串,也就是以表单里HTML控件的名字=控件值的方式,并且如果存在多个控件,彼此之间以“&”分割,那么我们就可以以控件名来获取控件值。获取HTML控件值常见有以下集中方式:
获取方式 | 表单提交方式 |
Request.QueryString["控件名"] | 适合于get方式提交的表单 |
Request.Form["控件名"] | 适合于post方式提交的表单 |
Request["控件名"] | 同时适合于get和post方式提交的表单 |
从上面我们可以看到用Request["控件名"]这种方式对于get和post两种方式都可行,那么我们就可以用这种方式来应付所有提交的表单。现在我们在“GetUserInfo.aspx”页面编写如下代码:
<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>注册表单提交的信息</title> </head> <body> 用户名:<%=Request["username"]%><br /> 密码:<%=Request["pwd"]%> </body> </html>
我们再次输入“zhoufoxcn”和“123456”并提交表单,得到如下画面:
得到了我们期望的效果。
乱码问题
对于上面的表单,我们在用户名和密码处分别输入“周公”和“123456”,会得到如下的结果,如下图:
这里用户就变成了“???”了,之所以出现这样的情况就是因为我们的编码原因。这就像我们在酒吧里对一个懂普通话的服务员说来一杯酒,他马上会送你一杯酒;可是当我们对一个不懂普通话的服务员用普通话说来一杯酒,他就会一头雾水了。
之所以出现乱码就是因为在这里客服端请求的编码和服务器响应的编码不一致,这个问题在《asp.net夜话之二:内置对象》中讲Request和Response对象的时候讲到过,没有看过的朋友请返回去看一下,这里只贴出结果:
从上面的图上我们看到默认情况下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编码中的一种,关于它们的编码原理有兴趣的朋友可以查询有关资料。
因为目前用Dreamweaver创建动态网页的时候默认都是采用gb2312编码(asp和jsp的程序员的网站编码很多都采用了这个默认值)。如果我们要想正确获取表单的值,我们可能就需要更改默认编码,对于上面的乱码问题,我们只需要更改Register.aspx页面就行,将Register.aspx页面的这部分更改一下:
- <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
更改为:
- <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="utf-8" %>
这样就能正常显示了,如下:
注意,使用Microsoft Visual Studio 2005创建网站的时候默认编码就是utf-8,无需更改。
服务器端表单
在此之前我们见到的表单都是如下格式:
<form action="接收数据页面" method="post">
并且我们都是利用的HTML控件。现在我们要介绍服务器端表单,服务器端表单与前面的表单相比,多了一个runat=”server”标记,如下:
<form id="form1" runat="server">
在服务器端表单里可以不用指定action属性,表示由当前页面处理,也可以不指定method属性,默认为post方式提交表单。在服务器端表单里,我们不光可以使用HTML控件,还可以使用HTML服务器控件,还可以使用asp.net控件(asp.net控件稍后会专门花篇幅介绍)。
另外需要注意的是,在一个asp.net页面中可以有多个不带runat=”server”标记的表单,但是只能有一个服务器端表单。
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服务器控件并且能正确运行的表单:
<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>服务器表单和HTML服务器控件</title> </head> <body> <form runat="server"> <input type="text" runat="server" id="txtUserName" /> <input type="password" runat="server" id="txtPassword" /> <input type="submit" runat="server" id="btnOK" value="提交" /> </form> </body> </html>
这个页面在浏览器端的HTML源代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>服务器表单和HTML服务器控件</title> </head> <body> <form name="ctl00" method="post" action="serverform.aspx" id="ctl00"> <div> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNTQ0MjI5MTUzZGR1mFZ52ODFgAKe7Qx9/67qMGFJCA==" /> </div> <input name="txtUserName" type="text" id="txtUserName" /> <input name="txtPassword" type="password" id="txtPassword" /> <input name="btnOK" type="submit" id="btnOK" value="提交" /> <div> <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWBAKIpeT6DgKl1bKzCQK1qbSRCwLdkpmPAcJ7Zy/C66ypRIq49nr3hQNayqwk" /> </div></form> </body> </html>
我们可以看到在客服端得到的HTML代码中都是标准的HTML代码,我们的文本框和密码框及服务器端提交按钮(因为它在服务器代码里也有runat=”server”标记)变成了如下代码:
<input name="txtUserName" type="text" id="txtUserName" />
<input name="txtPassword" type="password" id="txtPassword" />
<input name="btnOK" type="submit" id="btnOK" value="提交" />
也就是,所有的服务器控件经过服务器运行之后都会变成标准的HTML控件。这样我们可以得出一个结论:如果我们的控件功能本来就很简单,我们就可以直接使用HTML控件,这样就可以减轻服务器的负担,提高运行效率。另外,在上面的代码中多了一些以前我们没有见过的部分:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNTQ0MjI5MTUzZGR1mFZ52ODFgAKe7Qx9/67qMGFJCA==" />
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWBAKIpeT6DgKl1bKzCQK1qbSRCwLdkpmPAcJ7Zy/C66ypRIq49nr3hQNayqwk" />
因为服务器会保存服务器控件的状态和属性,所以它会利用一些隐藏域来保存这方面的信息,这部分的内容是经过Base64编码的。
服务器控件的好处是我们可以动态在代码中动态控制服务器控件的属性,对于上面的代码我们改造如下:
<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>服务器表单和HTML服务器控件</title> </head> <script runat="server"> protected void btnOK_Click(Object Src, EventArgs E) { Response.Write("用户名:"+this.txtUserName.Value); Response.Write("密码:"+this.txtPassword.Value); this.btnOK.Disabled=true; } </script> <body> <form runat="server"> <input type="text" runat="server" id="txtUserName" /> <input type="password" runat="server" id="txtPassword" /> <input type="submit" runat="server" id="btnOK" value="提交" onserverclick="btnOK_Click" /> </form> </body> </html>
上面代码中多了“<script runat="server"></script>”,并且提交按钮多了一个onserverclick="btnOK_Click"属性。在“<script runat="server"></script>”标记中我们写了一个protected void btnOK_Click(Object Src, EventArgs E)方法,这个方法符合System.EventHandler委托的标准。这个方法有两个参数,第一个表示由什么控件激发了这个事件,第二个参数表示事件发生时的一些相关信息。
在protected void btnOK_Click(Object Src, EventArgs E)方法中我们利用了类似WinForm中操作控件的方式来操作我们的服务器控件,这也就是为什么asp.net页面成为WebForm的原因。在这个方法里我们获取了控件的值,并最后将提交按钮禁用。
提交按钮的onserverclick属性值表示当这个按钮点击后由服务器上的哪个方法进行处理,这个方法要满足System.EventHandler委托的定义,这里我们写了btnOK_Click这个方法名。
这个页面初次运行的效果如下:
然后我们分别输入”zhoufoxcn”和”123456”,提交表单之后的效果如下:
我们看到在当前页面输出了表单控件的值,并且最后提交按钮呈现灰色状态,也就是被禁用了。
上面例子中我们确实就像在WinForm一样控制asp.net控件,非常方便。其实在asp.net开发中,用的最多的是asp.net服务器控件,而不是HTML服务器控件,asp.net控件提供了比HTML服务器控件更多的灵活性,以后的文章中会继续探讨asp.net控件。
实际上不管是HTML控件还是HTML服务器控件在asp.net里面用的都不是太多,介绍这部分主要是提及一些被Microsoft Visual Studio 2005隐藏的细节,还有其它动态页面与asp.net页面进行交互等问题。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhoufoxcn/archive/2008/09/18/2944967.aspx
发表评论
-
JS操作RadioButtonList
2009-12-16 23:25 3899function IsUpPic() { ... -
asp.net跳转页面的三种方法比较
2009-10-22 14:16 25431.Response.redir ... -
ASP.NET网站中的安全问题
2009-10-20 16:57 1194在网络经常看到网站被 ... -
新闻内容页分页的简单做法
2009-10-10 10:08 1226该例子只是提供了基本思路 很简单的做法,这个是假设数 ... -
Asp.net控件开发学习笔记(二)-控件开发基础
2009-10-03 16:49 1347接上篇…….. 看System.Web.UI.Ht ... -
Asp.net控件开发学习笔记-控件开发基础(一)
2009-10-03 16:33 1251服务器控件开发基础 当开发一个服务器控件时,首 ... -
Asp.net用户退出,清空Session,重定向登陆页面
2009-09-28 16:22 4179protected void Page_Load(object ... -
frameset中的aspx无法Postback
2009-09-28 16:07 1506<frameset cols="150,*&q ... -
.net页面定时刷新的几种简单方式
2009-09-28 11:20 59271: window.setTimeout("win ... -
动态添加TextBox
2009-09-21 16:30 1687方法1: 前台代码: <f ... -
浅谈ASP.NET管道优化
2009-09-20 21:43 1016ASP.NET管道优化 位于请求管道中的很多ASP.NET默 ... -
Asp.net 页面返回到上一页面
2009-09-20 21:20 916/// <summary> / ... -
PrecompiledApp.config文件和Global.asax 文件中的事件的关联
2009-09-19 10:24 2792在用Microsoft Visual Studio 2005开 ... -
gridview列 数字、货币和日期 显示格式
2009-09-11 17:05 1538在设置gridview等数据绑定控件的模版列时,总要 ... -
ASP.NET 打开新窗口几种方法
2009-09-09 21:44 3345ASP.NET打开新窗口方法一: Response ... -
response.addHeader("Content-Disposition","attachment; filename="+filename)中的中文乱码
2009-08-31 15:10 3251两种解决方法 1.如果web.config里utf-8 直接S ... -
技巧和诀窍:如何在VS 2005 SP1中使用VS的web服务器运行一个相对于根目录“/”的网站
2009-08-31 08:29 870大家常有一个疑问,是 ... -
Request.ServerVariables详细说明及代理
2009-08-14 10:46 2148ServerVariables是环境变量的集合。允许读取HTT ... -
DataList和Repeat无数据时提示暂无数据几种方法
2009-08-11 18:45 25761.放一个label DataTable table ... -
Asp.Net中清空所有textbox的几种方法
2009-08-08 08:53 5192用反射: FieldInfo[] info ...
相关推荐
三、 ASP.NET 夜话之 3 :表单和控件 四、 ASP.NET 夜话之 4 : Visual Studio 2005 中容易被忽略的技巧 五、 ASP.NET 夜话之 5 : Page 类和回调技术 六、 ASP.NET 夜话之 6 : ASP.NET 基本控件 七、 ASP.NET 夜话...
在ASP.NET 2.0中操作数据:为GridView控件添加Checkboxes列(源码)
在ASP.NET 2.0中操作数据:使用SqlDataSource控件查询数据(源码)
在ASP.NET 2.0中操作数据:在GridView控件中使用TemplateField
《Asp.net夜话》是一本专为ASP.NET初学者和进阶者设计的经典教程,共分为11章,深入浅出地介绍了ASP.NET的核心概念和技术。以下是对每一章内容的详细解读: 第一章:ASP.NET介绍 这一章是入门篇,主要介绍了ASP.NET...
本教程"ASP.NET经典教程 ASP.NET夜话"旨在帮助初学者快速入门,掌握ASP.NET的核心概念和技术。 1. **ASP.NET概述**: ASP.NET是一个服务器端的开发平台,它允许开发者使用各种编程语言(如C#、VB.NET)来创建动态...
ASP.NET_AJAX入门系列:Timer控件简单使用.doc ASP.NET_AJAX入门系列:UpdateProgress控件简单介绍.doc ASP.NET_AJAX入门系列:使用ScriptManagerProxy控件.doc ASP.NET_AJAX入门系列:使用ScriptManager控件.doc ...
在ASP.NET 2.0中操作数据:在GridView控件中使用TemplateField(源码)
ASP.NET夜话:从.NET的基础出发,在适当的地方加以延伸和拓展,使之更贴近企业开发。书中系统地讲解了。NET企业开发的多个层面,主要知识点包括:表单知识、.NET运行机制、Visual Studio 2008技巧、ASP.NET服务器...
在ASP.NET 2.0中操作数据:为GridView控件添加Checkboxes列
在ASP.NET 2.0中操作数据:在DetailsView控件中使用TemplateField
在ASP.NET 2.0中操作数据:数据控件的嵌套(源码)
《ASP.NET夜话》 周金桥 著 随书源代码 ☆ 章节清单:☆ 第02章 — ASP.NET基础 第03章 — 表单和控件 第05章 — Page类和回调技术 第06章 — ASP.NET基本控件 第07章 — ADO.NET介绍 第08章 — 数据绑定控件 第09...
在ASP.NET 2.0中操作数据:使用SqlDataSource控件查询数据
综上所述,《Asp.net夜话》这本书不仅涵盖了ASP.NET的基础知识,还深入讲解了其高级特性和实战技巧,是学习和进阶ASP.NET的宝贵资源。无论你是初学者还是经验丰富的开发者,都能从中受益匪浅,提升自己的Web开发能力...
《ASP.NET夜话》是由知名IT专家周金桥先生撰写的一部关于ASP.NET技术的著作,这本书以其深入浅出的讲解方式,深受初学者和有经验的开发者的喜爱。在提供的压缩包文件中,包含的“asp.net夜话”很可能是指一系列与该...
在ASP.NET 2.0中操作数据:DataList和Repeater数据分页
在ASP.NET 2.0中操作数据:数据控件的嵌套
NET企业开发的多个层面,主要知识点包括:表单知识、.NET运行机制、Visual Studio 2008技巧、ASP.NET服务器控件的使用、SQL注入防范、单元测试、三层架构、报表、数据加密/解密、GDI+、ADO.NET、分布式开发、AJAX...
在ASP.NET 2.0中操作数据:在DetailsView控件中使用TemplateField(源码)