HTML表单
HTML 表单用于收集用户输入。
HTML表单是用户和web站点或应用程序之间交互的主要内容之一。它们允许用户将数据发送到web站点。大多数情况下,数据被发送到web服务器,但是web页面也可以自己拦截它并使用它。
HTML表单是由一个或多个小部件组成的。这些小部件可以是文本字段(单行或多行)、选择框、按钮、复选框或单选按钮。
<form>元素
该元素正式定义了一个表单,它是一个容器元素,同时它在客户端定义如何发送数据,通过支持一些特定的属性来配置表单的行为方式。它的所有属性都是可选的,但至少要设置action
属性和method
属性。
<form action="test.html" method="post"> ... </form>
action
属性定义了发送数据要去的位置,它的值必须是一个有效的URL(绝对URL和相对URL均可)。如果没有提供此属性,则数据将被发送到包含表单的页面的URL。method
属性定义了发送数据的HTTP方法(如何发送数据),其中最常见的是GET
方法(默认)和POST
方法。
<form> 属性的列表:
表单元素
表单元素指的是不同类型的 input 元素、复选框、单选按钮、提交按钮等等。
<input> 元素
<input> 元素根据不同的 type 属性,可以变化为多种形态。
输入类型:text
<input type="text"> 定义供文本输入的单行输入字段,实例如下:
<form> First name:<br> <input type="text" name="firstname"> <br> Last name:<br> <input type="text" name="lastname"> </form>
输入类型:password
<input type="password"> 定义密码字段,password 字段中的字符会被做掩码处理(显示为星号或实心圆)。
输入类型:submit
<input type="submit"> 定义提交表单数据至表单处理程序的按钮。
表单处理程序(form-handler)通常是包含处理输入数据的脚本的服务器页面。在表单的 action 属性中规定表单处理程序(form-handler),实例如下(value属性定义默认值):
<form action="/demo/demo_form.asp"> user-name:<br> <input type="text" name="firstname" value="Mickey"> <br> password:<br> <input type="password" name="psw"><br> <input type="submit" value="Submit"> </form>
输入类型:radio
<input type="radio"> 定义单选按钮,name属性定义一组单选按钮,只可选择一组中的一个,不同组则无此限制,checked属性定义默认选中项,实例如下:
<form> <input type="radio" name="sex" value="male" checked>Male <br> <input type="radio" name="sex" value="female">Female </form>
输入类型:checkbox
<input type="checkbox"> 定义复选框,复选框允许用户在有限数量的选项中选择零个或多个选项,实例如下:
<form> <input type="checkbox" name="vehicle" value="Bike">I have a bike <br> <input type="checkbox" name="vehicle" value="Car">I have a car </form>
输入类型:button
<input type="button> 定义按钮。
<input type="button" onclick="alert('Hello World!')" value="Click Me!">
HTML5输入类型:color
<input type="color"> 用于应该包含颜色的输入字段,根据浏览器支持,颜色选择器会出现输入字段中。
<form> Select your favorite color: <input type="color" name="favcolor"> </form>
Chrome:
Firefox:
HTML5输入类型:data
<input type="date"> 用于应该包含日期的输入字段,根据浏览器支持,日期选择器会出现输入字段中。实例1如下:
<form action=""> Birthday: <input type="date" name="bday"> <input type="submit"> </form>
Chrome:
ie:
Firefox:
实例2:
<form action="/demo/demo_form.asp"> 请输入 1980-01-01 之前的日期:<br> <input type="date" name="bday" max="1979-12-31"><br><br> 请输入 2000-01-01 之后的日期:<br> <input type="date" name="bday" min="2000-01-02"><br><br> <input type="submit"> </form>
HTML5输入类型:datatime
<input type="datetime"> 允许用户选择日期和时间(有时区)。根据浏览器支持,日期选择器会出现输入字段中。
<form> Birthday (date and time): <input type="datetime" name="bdaytime"> </form>
Chrome:
HTML5输入类型:datatime-local
<input type="datetime-local"> 允许用户选择日期和时间(无时区),根据浏览器支持,日期选择器会出现输入字段中。
<form> Birthday (date and time): <input type="datetime-local" name="bdaytime"> </form>
Chrome:
HTML5输入类型:email
<input type="email"> 用于应该包含电子邮件地址的输入字段。根据浏览器支持,能够在被提交时自动对电子邮件地址进行验证。某些智能手机会识别 email 类型,并在键盘增加 ".com" 以匹配电子邮件输入.
<form> E-mail: <input type="email" name="email"> </form>
Chrome:
Firefox:
IE:
HTML5输入类型:month
<input type="month"> 允许用户选择月份和年份,根据浏览器支持,日期选择器会出现输入字段中。
<form> Birthday (month and year): <input type="month" name="bdaymonth"> </form>
Chrome:
HTML5输入类型:number
<input type="number"> 用于应该包含数字值的输入字段,能够对数字做出限制,根据浏览器支持,限制可应用到输入字段。IE9 及早期版本不支持 type="number",实例(输入限制在1到5)如下:
<form> <input type="number" name="quantity" min="1" max="5"> </form>
HTML5输入类型:range
<input type="range"> 用于应该包含一定范围内的值的输入字段,根据浏览器支持,输入字段能够显示为滑块控件。可使用如下属性来规定限制:min、max、step、value。实例:
<form> <input type="range" name="points" min="0" max="10"> </form>
Chrome:
Firefox:
HTML5输入类型:search
<input type="search"> 用于搜索字段(搜索字段的表现类似常规文本字段).
<form> Search Google: <input type="search" name="googlesearch"> </form>
Chrome:
HTML5输入类型:tel
<input type="tel"> 用于应该包含电话号码的输入字段。目前只有 Safari 8 支持 tel 类型。
<form> Telephone: <input type="tel" name="usrtel"> </form>
HTML5输入类型:time
<input type="time"> 允许用户选择时间(无时区),根据浏览器支持,时间选择器会出现输入字段中。
<form> Select a time: <input type="time" name="usr_time"> </form>
Chrome:
Firefox:
HTML5输入类型:url
<input type="url"> 用于应该包含 URL 地址的输入字段。根据浏览器支持,在提交时能够自动验证 url 字段。某些智能手机识别 url 类型,并向键盘添加 ".com" 以匹配 url 输入.
<form> Add your homepage: <input type="url" name="homepage"> </form>
Chrome:
IE:
Firefox:
HTML5输入类型:week
<input type="week"> 允许用户选择周和年,根据浏览器支持,日期选择器会出现输入字段中
<form> Select a week: <input type="week" name="week_year"> </form>
Chrome:
注释:老式 web 浏览器不支持的HTML5输入类型,会被视为输入类型 text。
常用输入限制
属性 | 描述 |
disabled | 规定输入字段应该被禁用 |
max | 规定输入字段的最大值 |
maxlength | 规定输入字段的最大字符数 |
min | 规定输入字段的最小值 |
pattern | 规定通过其检查输入值的正则表达式 |
readonly | 规定输入字段为只读(无法修改) |
required | 规定输入字段是必需的(必需填写) |
size | 规定输入字段的宽度(以字符计) |
step | 规定输入字段的合法数字间隔 |
value | 规定输入字段的默认值 |
<select> 元素(下拉列表)
实例:
<select name="cars"> <option value="volvo">Volvo</option> <option value="saab" selected>Saab</option> <option value="fiat">Fiat</option> </select>
<option> 元素定义待选择的选项。列表通常会把首个选项显示为被选选项。可以通过添加 selected 属性来定义预定义选项。
<textarea> 元素
定义多行输入字段(文本域),实例如下,每行最多30个字符:
<textarea name="message" rows="10" cols="30"> The cat was playing in the garden. </textarea>
<button> 元素
定义可点击的按钮
<button type="button" onclick="alert('Hello World!')">Click Me!</button>
HTML5 表单元素:<datalist>
为 <input> 元素规定预定义选项列表,用户会在他们输入数据时看到预定义选项的下拉列表,<input> 元素的 list 属性必须引用 <datalist> 元素的 id 属性。实例如下:
Safari 或 IE9(以及更早的版本)不支持 datalist 标签。
<form action="/demo/demo_form.asp"> <input list="browsers" name="browser"> <datalist id="browsers"> <option value="Internet Explorer"> <option value="Firefox"> <option value="Chrome"> <option value="Opera"> <option value="Safari"> </datalist> <input type="submit"> </form>
HTML5 表单元素:<keygen>
<keygen> 标签规定用于表单的密钥对生成器字段。当提交表单时,私钥存储在本地,公钥发送到服务器。所有主流浏览器都支持 <keygen> 标签,除了 Internet Explorer 和 Safari。
HTML5 表单元素:<output>
<output> 标签定义不同类型的输出,比如脚本的输出。
用button做按钮和用input来做按钮有什么区别?
<input type="submit" value="OK" />,一定要这样闭合。而不是:<input type="submit" value="OK" ></input>。input起始标签为必须,而关闭标签是禁止的。<button>比<input>更厉害的地方就在于它可以包含内容。它的值并不是写在value属性里,而是包含在标签中。如:<button>OK</button>。<button>的起始标签和关闭标签都是必须的。你可以这样写:<button><strong>OK</strong>, I do.</button>,甚至是插入图片:<button><img src="button.gif" alt="" />, it's great.</button>。
被<button>包含的图片,不能使用热点地图,即不能<img src="foo.gif" usemap="..." />,这是不合法的。当然也不能再包含诸如input, select, textarea, label, button, form, fieldset, iframe,和isindex(不推荐使用)元素。
发送表单数据
参考MDN web docs:发送表单数据
客户端/服务器体系结构
web基于非常基本的客户端/服务器体系结构,可以总结如下:客户端(通常是web浏览器)向服务器发送请求(大多数情况下是Apache、Nginx、IIS、Tomcat等web服务器),使用HTTP 协议。服务器使用相同的协议来回答请求。
在客户端,HTML表单是一种方便的用户友好的方式,可以配置HTTP请求将数据发送到服务器。
表单提交方式中POST和GET的区别:
GET方法是浏览器使用的方法,请求服务器返回给定的资源,在这种情况下,浏览器发送一个空的主体。因为主体是空的,如果使用该方法发送一个表单,那么发送到服务器的数据将被追加到URL。
<form action="http://baidu.com" method="get"> <div> <label for="user">用户名</label> <input name="user" id="user" value="Lily"> </div> <div> <label for="age">年龄</label> <input name="age" id="age" value="25"> </div> <div> <button>提交</button> </div> </form>
-->由于
GET
方法已经被使用,提交表单后-->
GET会修改网址,数据被附加到URL作为一系列的名称/值对,在URL web地址结束之后,我们包括一个问号(?
),后面是名称/值对,每一个都由一个与符号(&
)分隔开。
HTTP请求如下:
HTTP/1.1
Host: baidu.com如果使用POST方法发送表单,则将数据追加到HTTP请求的主体中。
POST会把提交内容放入http的Headers中(F12 Network可查看All--Name标签页下)
<form action="http://foo.com" method="post"> <div> <label for="say">What greeting do you want to say?</label> <input name="say" id="say" value="Hi"> </div> <div> <label for="to">Who do you want to say it to?</label> <input name="to" value="Mom"> </div> <div> <button>Send my greetings</button> </div> </form>
主体中包含的数据是这样的:
POST / HTTP/1.1 Host: foo.com Content-Type: application/x-www-form-urlencoded Content-Length: 13 say=Hi&to=Mom
Content-Length数据头表示主体的大小,Content-Type
数据头表示发送到服务器的资源类型。
使用GET
请求用户将在他们的URL栏中看到数据,而使用POST
请求用户将不会看到。这一点很重要,有两个原因:
- 如果您需要发送一个密码(或其他敏感数据),永远不要使用
GET
方法否则数据会在URL栏中显示,这将非常不安全,POST 的安全性更好,因为在页面地址栏中被提交的数据是不可见的。。 - 如果您需要发送大量的数据,那么
POST
方法是首选的,因为一些浏览器限制了URL的大小。此外,许多服务器限制它们接受的URL的长度。
常见的安全问题
每次向服务器发送数据时,都需要考虑安全性。到目前为止,HTML表单是最常见的攻击媒介(可能发生攻击的地方)。这些问题从来都不是来自HTML表单本身,它们来自于服务器如何处理数据。
XSS和CRSF
跨站脚本(XSS)和跨站点请求伪造(CSRF)是常见的攻击类型,它们发生在当您将用户发送的数据显示给用户或另一个用户时。
XSS允许攻击者将客户端脚本注入到其他用户查看的Web页面中。攻击者可以使用跨站点脚本攻击的漏洞来绕过诸如同源策略之类的访问控制。这些攻击的影响可能从一个小麻烦到一个重大的安全风险。
CSRF攻击类似于XSS攻击,因为它们以相同的方式攻击——向Web页面中注入客户端脚本——但它们的目标是不同的。CSRF攻击者试图将特权升级到特权用户(比如站点管理员)的权限,以执行他们不应该执行的操作(例如,将数据发送给一个不受信任的用户)。
XSS攻击利用用户对web站点的信任,而CSRF攻击则利用网站为其用户提供的信任。
为了防止这些攻击,您应该始终检查用户发送给服务器的数据(如果需要显示),尽量不要显示用户提供的HTML内容。相反,您应该处理用户提供的数据,这样您就不会逐字地显示它。当今市场上几乎所有的框架都实现了一个最小的过滤器,它可以从任何用户发送的数据中删除HTML<script>
、<iframe>
和<object>
元素。这有助于降低风险,但并不一定会消除风险。
SQL注入
SQL 注入是一种试图在目标web站点使用的数据库上执行操作的攻击类型。这通常包括发送一个SQL请求,希望服务器能够执行它(通常,当应用服务器试图存储由用户发送的数据时)。这实际上是攻击网站的主要途径之一。
其后果可能是可怕的,从数据丢失到通过使用特权升级控制整个网站基础设施的攻击。这是一个非常严重的威胁,您永远不应该存储用户发送的数据,而不执行一些清理工作(例如,在php/mysql基础设施上使用mysql_real_escape_string()
。
HTTP数据头注入和电子邮件注入
当您的应用程序基于表单上用户的数据输入构建HTTP头部或电子邮件时,就会出现这种类型的攻击。这些不会直接损害您的服务器或影响您的用户,但是它们是一个更深入的问题,例如会话劫持或网络钓鱼攻击。
这些攻击大多是无声的,并且可以将您的服务器变成僵尸
设计+表单
在开始编写代码之前,花时间考虑一下您的表单。设计一个快速的模型可以帮助我们定义想要询问用户的正确的数据集。从用户体验(UX)的角度来看,要记住:表单越大,失去用户的风险就越大。保持简单,保持专注:只要求必要的数据。在构建站点或应用程序时,设计表单是非常重要的一步。