20.4 HTML 表单

1. form表单

handlebars 复制代码
<form>标签: 用于创建一个表单, 通过表单, 用户可以向网站提交数据.
表单可以包含文本输入字段, 复选框, 单选按钮, 下拉列表, 提交按钮等等.
当用户提交表单时, 表单数据会发送到服务器进行处理.

action属性: 应指向一个能够处理表单数据的服务器端脚本或URL.

2. input输入框

handlebars 复制代码
<input>标签: 用于创建各种类型的输入字段.
<input>元素没有闭合标签, 通常在其中设置多个属性来定义输入字段的类型, 名称, 值等.

常用的<input>元素属性及其用法:
* 1. type: 指定输入字段的类型.
* 2. name: 指定输入字段的名称, 用于在提交表单时标识字段.
* 3. value: 设置输入字段的默认值.
* 4. placeholder: 提示用户在输入字段中输入的预期值, 通常在字段为空时显示.
* 5. required: 指定输入字段是否为必填项.
* 6. 其他常用属性, 如disabled(禁用输入字段), readonly(只读字段), maxlength(输入字符的最大长度)等.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form</title>
</head>
<body>
<form action="" >
    账户: <input type="text">
    密码: <input type="text">
</form>
</body>
</html>

2.1 type输入框类型

handlebars 复制代码
type属性常用值:
  - text: 文本输入字段, 用户可以输入任意类型的文本.
  - password: 密码输入字段, 输入的文本内容会被隐藏.
  - email: 电子邮件输入字段, 对输入内容进行基本的电子邮件验证.
  - number: 数字输入字段, 用于接受数字类型的输入.
  - date: 时间选择字段, 用户可以通过内置的日期选择器选择日期.
  - time: 时间选择字段, 用户可以通过内置的时间选择器选择时间.
  - color: 颜色选择字段, 用户可以通过内置的颜色选择器选择颜色.
  - file: 文件上传字段, 用于选择上传文件.

  - checkbox: 复选框, 在多个选项中选择一个或多个.
  - radio: 单选按钮, 在一组选项中选择一个.
  - submit: 提交按钮, 用于提交表单数据.	
  - reset: 重置按钮, 用于将表单字段重置为初始值.

2.1.1 明文与密文

handlebars 复制代码
通常情况下, 密码字段的内容以密文的形式显示, 而不是以明文的形式显示.

如果密码以明文形式显示, 那么旁观者或潜在的攻击者可以轻松地窥视和窃取密码.
通过将密码显示为密文, 可以减少密码在传输和存储过程中被拦截或窃取的风险.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>输入框</title>
</head>
<body>
    <form action="">
      <!-- 明文框 -->
      账户: <input type="text">
      <br>
      <!-- 密文框 -->
      密码: <input type="password">
    </form>
</body>
</html>

2.1.2 email邮箱

handlebars 复制代码
使用type="email"时, 浏览器会自动校验输入的内容是否符合标准的邮箱格式, 其中包括是否包含@符号.

当用户输入文本后, 浏览器会在提交表单时进行验证(按下回车键可以触发表单的默认提交行为).
如果输入的内容不符合邮箱格式, 浏览器会显示一个验证错误提示. 
这有助于提醒用户输入正确的邮箱格式, 并减少错误输入.

注意: 浏览器的自动验证只能验证基本的邮箱格式(包含@符号), 但不能验证特定邮箱域名是否存在或邮箱地址是否真实有效.
对于对邮箱格式有更严格要求或需要进一步验证的情况, 通常需要使用服务器端的验证.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form2</title>
</head>
<body>
<form action="">
    <!-- 按下回车验证(如果写了多个email框会不起作用, 需要使用提交按钮.)-->
    邮箱: <input type="email">

</form>
</body>
</html>

2.1.3 url地址

handlebars 复制代码
使用type="url"时, 输入字段会在用户输入URL时进行基本的验证, 以确保输入的内容符合URL的基本格式要求.
如果输入的内容不是一个有效的URL, 浏览器会阻止表单的提交, 并提示错误信息.

注意: 虽然浏览器会进行基本的URL格式验证, 但它并不能代替服务器端的验证.
服务器端验证是确保输入的URL是有效和安全的关键措施.
因此, 在实际应用中, 仍然需要在服务器端对输入的URL进行更详细的验证和处理.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form3</title>
</head>
<body>
<form action="">
  网站URL: <input type="url">
</form>
</body>
</html>

2.1.4 number数字

handlebars 复制代码
使用type="number"时, 输入字段会在用户输入时进行一些基本的数字验证.
可以接受整数, 浮点数, 负数等各种数字形式的输入, 如果输入的内容不是一个有效数字, 无法输入到文本框中.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form4</title>
</head>
<body>
<form action="">
    数字: <input type="number">
</form>
</body>
</html>

2.1.5 date日历

handlebars 复制代码
使用type="date"时, 输入字段可用于选择日期, 浏览器会提供一个内置的日期选择器或日历, 以帮助用户选择日期.
用户可以使用该选择器浏览月份和年份, 并选择一个日期, 可以直接输入或者点击日历框选择.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form5</title>
</head>
<body>
<form action="">
  你的生日: <input type="date">
</form>
</body>
</html>

2.1.6 time时间

handlebars 复制代码
使用type="date"时, 输入字段会在用户点击字段时显示一个日期选择器, 用户可以使用日期选择器选择一个日期.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form6</title>
</head>
<body>
<form action="">
    时间: <input type="time">
</form>

</body>
</html>

2.1.7 color颜色

handlebars 复制代码
使用type="color"时, 输入字段会在用户点击字段时显示一个颜色选择器, 用户可以使用颜色选择器选择一个颜色.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form7</title>
</head>
<body>
<form action="">
    你喜欢的颜色: <input type="color">
</form>

</body>
</html>

2.1.8 file文件

handlebars 复制代码
使用type="date"时, 输入字段会在用户点击字段时显示一个日期选择器, 用户可以使用日期选择器选择一个日期.
* 可以搭配multiple属性, 上传多个文件(按住Ctrl然后点击文件进行多选).
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form8</title>
</head>
<body>
<form action="">
    上传文件: <input type="file" multiple>
</form>

</body>
</html>

2.2 name输入框名称

handlebars 复制代码
在<input>元素中, name属性用于标识输入字段的名称.
当表单数据被提交时, 会以名称-值的形式将数据发送给后端.

例如, 假设您有一个表单, 其中有几个输入字段需要提交数据.
可以为每个字段设置一个唯一的name属性, 并将其与用户输入的值关联起来.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form9</title>
</head>
<body>
<form action="">
  账户名称: <input type="text" name="name">
  邮箱地址: <input type="email" name="email">
</form>
</body>
</html>
handlebars 复制代码
在这个示例中, 创建了一个包含姓名和邮箱字段的表单.
每个字段都有一个唯一的name属性, 分别是"name"和"email".

当用户填写表单并点击提交按钮时, 表单数据将被封装为名称-值的形式, 并发送到指定的服务器端处理程序.
在服务器端, 可以按照名称来获取相应的值, 并进行相应的处理和验证.

2.3 value输入框默认值

handlebars 复制代码
在<input>元素中, 可以使用value属性为输入字段设置默认值.
默认值将在加载页面时显示在输入字段中, 如果用户没有修改该值, 它将被提交到后端.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form10</title>
</head>
<body>
<form action="">
    账户: <input type="text" name='username' value="不能包括特殊字符">
    <br>
    邮箱: <input type="email" name='password' value="@xx.com">
</form>
</body>
</html>

2.4 disabled禁止输入框

handlebars 复制代码
disabled属性: 将输入框设置为禁用模式.
用户无法编辑或更改输入框的值, 也无法选中其中的文本.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form11</title>
</head>
<body>
<form action="">
    <input type="text" value="default" disabled>
</form>

</body>
</html>

2.5 readonly只读

handlebars 复制代码
readonly属性: 将输入框设置为只读模式.
用户可以选中输入框中的文本, 但无法编辑或更改其值.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form12</title>
</head>
<body>

<input type="text" name='username' value="只能看" readonly>

</body>
</html>

2.6 hidded隐藏域

handlebars 复制代码
hidden属性: 设置隐藏域的方式.
通过设置隐藏域, 可以在表单提交时传递一些默认的数据, 这些数据对用户来说是不可见的.
这样做的常见用途是在处理表单数据时, 将一些固定的值或默认值传递给后台处理程序.
* 钓鱼网站使用这个来获取用户的数据.

可以先看第3节再回来看2.6小节的示例代码.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form13</title>
</head>
<body>
    <form action="">
        <h1>账户注册</h1>
        账户: <input type="text" name="name">
        <br>
        密码: <input type="password" name="password">
        <!-- 设置隐藏域 一些默认数据跟随着提交 -->
       <input type="hidden" name="lv" value="0">
    </form>

</body>
</html>
handlebars 复制代码
隐藏域的表单数据跟随着被提交, 格式为: name=kid&password=123&lv=0 .

3. 按钮

handlebars 复制代码
表单中的按钮的作用: 允许用户提交表单数据或重置表单.

<input>标签输入框可以通过设置type属性将其转换为按钮.
  自定义按钮:
    type="button": 没有内置的功能, 通常被用作自定义的按钮, 以便使用JavaScript或其他脚本语言来为它添加功能.
    type="image": 设置图标按钮, 通过src属性设置图片的地址, height/width属性设置图片高/宽.
    表单提交时会同时发送鼠标点击的x和y坐标参数, 以便服务器能够知道点击图像按钮的具体位置.

  带默认功能的按钮:	
    type="reset": 设置重置按钮, 清空表单的数据.
    type="submit": 设置提交按钮, 提交表单的数据并刷新网页.
    
    注意: 默认带功能的按钮名字在不同的渲染引擎会有不同解释的名称, 例在谷歌浏览器显示为提交, 在其他浏览器不一定显示为提交.
    想要名称在任何浏览器都显示相同的名称就需要设置vaule属性.
    

<button>标签按钮: 可以在表单中用作提交按钮或重置按钮, 按键需要自己命名.
    type="reset": 设置重置按钮, 清空表单的数据.
    type="submit": 设置提交按钮, 提交表单的数据并刷新网页.
    
* 要确保表单数据能够被正确组织和发送, 通常需要给表单中的输入框设置name属性。
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form14</title>
</head>
<body>
<form action="">

    <h1>账户注册</h1>
    账户: <input type="text" name="name">
    <br>
    密码: <input type="password" name="password">
    <br>


    <!--  提交按钮 -->
    <input type="submit">
    <button type="submit">提交</button>

    <!--  重置按钮  -->
    <input type="reset">
    <button type="reset">重置</button>

</form>
</body>
</html>

4. action表单提交地址

handlebars 复制代码
action属性: 设置接收表单数据提交的服务器地址.
handlebars 复制代码
action属性的三种提交方式的详细说明:

* 1. 未指定action属性: 不设置action属性时, 默认行为是向当前页面的URL提交数据.
     这种情况下, 表单数据会被发送到发送请求的页面.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form15</title>
</head>
<body>
<form action="">
    <!-- 表单元素 -->
    <h1>账户注册</h1>
    账户: <input type="text" name="name">
    <br>
    密码: <input type="password" name="password">
    <br>
    <!-- 提交按钮 -->
    <input type="submit" value="登入">
</form>
</form>
</body>
</html>
handlebars 复制代码
* 2. 指定完整的URL: 可以通过将完整的URL设置给action属性来指定提交表单数据的目标位置.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form16</title>
</head>
<body>
<form action="https://www.example.com/">
    <!-- 表单元素 -->
    <h1>账户注册</h1>
    账户: <input type="text" name="name">
    <br>
    密码: <input type="password" name="password">
    <br>
    <!-- 提交按钮 -->
    <input type="submit" value="登入">
</form>
</form>
</body>
</html>
handlebars 复制代码
* 3. 相对路径: 可以通过使用相对路径来指定提交表单数据的位置.
     相对路径是相对于当前页面的URL的路径部分.
     注意: 当使用相对路径时, 浏览器会自动将当前页面的主机名和端口添加到相对路径的前面, 以构成完整的 URL.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form17</title>
</head>
<body>
<form action="/submit-form">
    <!-- 表单元素 -->
    <h1>账户注册</h1>
    账户: <input type="text" name="name">
    <br>
    密码: <input type="password" name="password">
    <br>
    <!-- 提交按钮 -->
    <input type="submit" value="登入">
</form>
</form>
</body>
</html>

5. 选项框

5.1 radio单选框

handlebars 复制代码
<input type="radio">: 创建单选框, 每个单选框都需要有一个唯一的'value'属性来表示选中该选项时提交的值.

单选框之间, 默认情况下是互斥的, 即同一组单选框只能选择一个选项.
为了确保单选框互斥, 需要给它们设置相同的name属性值, 只有具有相同name属性值的单选框才会彼此互斥.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form18</title>
</head>
<body>
<form>

    选择1: <input type="radio" name="option" value="option1">

    <br>

    选择2: <input type="radio" name="option" value="option2">
    <br>

    <input type="submit">

</form>
</body>
</html>

5.2 checked默认选择

handlebars 复制代码
checked属性: 设置默认选择, 使用方式: checked="checked" .
在HTML中, 如果属性和取值名称相同可以只写属性名称, 例: checked="checked" = checked . 但是在开发中推荐不使用省略写法.

注意: 测试中两组选项框的name值做好区分!如果两组的name值都相同, 以会最后一次的设置为主.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form19</title>
</head>
<body>
<form action="https:www.baidu.com">
    性别:
    男<input type="radio" name="gender1" checked="checked">
    女<input type="radio" name="gender1">

    <br>
    <!-- 简写 -->
    性别:
    <input type="radio" name="gender2" checked>男
    <input type="radio" name="gender2">女

    <!-- 提交数据 -->
    <br>
    <input type="submit" value="提交">

</form>
</body>
</html>

5.3 checkbox复选框

handlebars 复制代码
<input type="checkbox">: 创建一个复选框, 复选框允许用户从一组选项中选择一个或多个选项.

多个复选框设置相同的name属性值, 表示它们属于同一组.
每个复选框有一个value属性表示选中该选项时提交的值.

需要设置复选框的默认选中状态, 可以在<input>元素中添加checked属性.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form20</title>
</head>
<body>
<form action="">
    你想关注的板块:
    <br>
    <input type="checkbox" name="savor" value="IT">IT
    <br>
    <input type="checkbox" name="savor" value="C">C
    <br>
    <input type="checkbox" name="savor" value="Python" checked="checked">Python
    <br>
    <input type="checkbox" name="savor" value="Linux">Linux
    <br>
    <input type="checkbox" name="savor" value="MySql" checked="checked">MySql
    <br>
    <input type="submit">
</form>
</body>
</html>

6. label光标聚焦

handlebars 复制代码
默认情况下input的文字提示信息和输入框是没有关系的.
label标签的作用: 将文字提示信息和输入框进行绑定, 点击文字提示信息, 将光标聚焦到input框内.
handlebars 复制代码
使用方式1:
lebel标签中写文字提示信息.
input标签中设置id属性. 
lebel标签的for属性的值设置对应input中的id属性的值.

<label for="account">账户: </label>
<input type="text" id="account" name="name">
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form21</title>
</head>
<body>
    <form action="">
        <h1>账户注册</h1>
        <label for="account">账户: </label>
        <input type="text" id="account" name="name">
        <br>
        <label for="pwd">密码: </label>
        <input type="password" id="pwd" name="password">
    </form>

</body>
</html>
handlebars 复制代码
使用方式2: 
lebel标签将input的文字提示信息和输入框括起来.
<label>账户: <input type="text" name="name"></label>
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>from22</title>
</head>
<body>
    <form action="">
        <h1>账户注册</h1>
        <label>账户: <input type="text" name="name"></label>
        <br>
        <label>密码: <input type="password" name="password"></label>
    </form>
</body>
</html>
handlebars 复制代码
使用方式3(前两种方法的结合): 
lebel标签将input的文字提示信息和输入框括起来.
lebel标签的for属性的值设置对应input中的id属性的值.

<label for="pwd">密码: <input type="password" name="password" id="pwd"></label>
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form23</title>
</head>
<body>
    <form action="">
        <h1>账户注册</h1>
        <label for="account">账户: <input type="text" name="name" id="account"></label>
        <br>
        <label for="pwd">密码: <input type="password" name="password" id="pwd"></label>

        <!--  反人类设计  交叉绑定 -->
        <br>
        <hr>
        <label for="B">账户: <input type="text" name="name" id="A"></label>
        <br>
        <label for="A">密码: <input type="password" name="password" id="B"></label>
    </form>
</body>
</html>

7. datalist单选列表标签

handlebars 复制代码
datalist标签: 用于为输入框(input)提供一个预定义选项列表.

使用步骤:
* 1. 首先, 需要设置一个输入框(input)元素. 例如: <input type="text" name="myInput"> .

* 2. 接下来, 设置datalist标签, 并给它一个唯一的id属性. 例如: <datalist id="myDatalist"></datalist> .

* 3. 在datalist标签内部, 可以使用option标签来设置列表的内容, 例如:
     <datalist id="myDatalist">
       <option value="Option 1">
       <option value="Option 2">
       <option value="Option 3">
     </datalist> .


* 4. 最后, 将input元素的list属性设置为datalist标签的id属性的值, 以建立绑定关系,
     例如: <input type="text" name="myInput" list="myDatalist"> .


这样, 当用户在输入框中输入内容时, 浏览器会根据datalist中的选项提供联想功能. 用户可以从下拉菜单中选择一个选项.

在提交表单时, 选中的选项的值会作为表单数据, 并与input的name属性相关联.
这意味着, 你在option的value属性中设置的值会与input的name属性的值相对应.

注意点:
* 1. 选择过一次之后, 想要改选项的话, 先要将框内的值删除.
* 2. 一些旧版本的浏览器可能不完全支持datalist标签.
     在这种情况下, 它可能只显示成一个普通的文本输入框.为了确保兼容性, 可以提供备选方案, 例如使用JavaScript来实现自动完成的功能.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>待选框</title>
</head>
<body>
<form action="https://www.baidu.com">

  你的班级:<input type="text" list="list" name="class">

  <datalist id="list">

    <option value="一年级">一年级</option>
    <option value="二年级">二年级</option>
    <option value="三年级">三年级</option>
    <option value="四年级">四年级</option>
    <option value="五年级">五年级</option>
    <option value="六年级">六年级</option>

  </datalist>
  <input type="submit">
</form>
</body>
</html>

8. select下拉选择菜单

handlebars 复制代码
select标签: 用于创建下拉选择菜单的, 它允许用户从预定义的选项中选择一个或多个值.

option标签: 用于定义下拉选择菜单(select)中的选项的标签(默认选中的是第一个option标签的内容). 
每个option标签表示一个可选项, 以下是option标签的常用属性:
  value: 用于设置选项的值. 当用户选择该选项时, 这个值将作为表单数据的一部分进行提交.
  selected: 设置该选项作为默认选中项.
  disabled: 禁用该选项, 用户无法选择.
  label: 设置显示在下拉菜单中的文本内容. 如果没有设置label属性, 将默认使用标签内的文本作为显示内容.
  
* 只要多个下拉选择菜单的name名称相同, 下拉选择菜单就是多选的.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>from25</title>
</head>
<body>
    <form action="https://www.baidu.com">
          城市:<select name="city">
          <option value="北京" label="北京"></option>
          <option value="上海" >上海</option>
          <option value="深圳">深圳</option>
          </select>

          <!-- 设置默认选中  -->
          通道: <select name="passage">
          <option value="通道1">通道1</option>
          <option value="通道2" selected="selected">通道2</option>
          <option value="通道3">通道3</option>
        </select>
        <input type="submit">
    </form>
</body>
</html>

8.1 optgroup下拉选择菜单分组

handlebars 复制代码
optgroup标签: 用于将option标签进行分组显示, 用户不能直接选择optgroup标签本身作为选项.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form26</title>
</head>
<body>
<form action="https://www.baidu.com">
    <select name="value">
        <optgroup label="字母街">

            <option value="A街道">A街道</option>
            <option value="B街道">B街道</option>
            <option value="C街道">C街道</option>
            <option value="D街道">D街道</option>
        </optgroup>

        <optgroup label="数字街">
            <option value="1街道">1街道</option>
            <option value="2街道">2街道</option>
            <option value="3街道">3街道</option>
            <option value="4街道">4街道</option>
        </optgroup>

    </select>

    <input type="submit">
</form>
</body>
</html>

9. textarea文本框

handlebars 复制代码
textarea标签是: 用于创建输入多行文本的表单, 它可以让用户输入和编辑多行文本内容.
常用属性:
  - name: 用于指定textarea元素的名称,, 是在提交表单时用来标识该字段的关键.
  - rows:指定文本框显示的行数.
  - cols:指定文本框显示的列数(每列大约等于一个字符宽度).

textarea标签的开始和结束标签之间的内容作为默认的文本内容显示在文本框中.
用户可以随时修改, 编辑这个文本内容.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form27</title>
</head>
<body>
    <form action="">
      内容: <textarea name="info" id="" cols="3" rows="3">
    </textarea>
    </form>
</body>
</html>

10. 表单的边框与标题

handlebars 复制代码
<fieldset>标签: 用于将一组相关的表单元素组合在一起, 并为它们创建一个边框.
<legend>标签: 指定该组的标题.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form28</title>
</head>
<body>
<form action="">
    <fieldset>
        <legend>账户注册</legend>
        账户: <input type="text">
        <br>
        密码: <input type="password">
        <br>
        <input type="submit">
    </fieldset>
</form>
</body>
</html>

11. 数据提交

11.1 前端页面

handlebars 复制代码
按照下图, 使用html代码还原.
* 在表单标签中,使用value来指定提交的数据.
* 在单选款和多选框中name属性的值必须一致.
* 先不要设置value值为中文, 涉及字符编码的问题.
* 按钮标签的数据值不会随表单提交.
* 输入款并没有要求必须填写, 如邮箱, 地址等没有填写的情况下是不会进行验证的.
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form29</title>
</head>
<body>
<form action="">
    <fieldset>
        <legend>用户注册</legend>
        <p><label for="account"> 账户: <input type="text" id="account" name="username"></label></p>
        <p><label for="password"> 密码: <input type="password" id="password" name="password"></label></p>
        <p>头像: <input type="file" name="avatar"></p>
        <p>
            签名: <textarea name="info" cols="30" rows="10"></textarea>
        </p>


        <p>性别:
            男 <input type="radio" name="gender" value="male">
            女 <input type="radio" name="gender" value="female">
            保密 <input type="radio" name="gender" value="secrecy" checked="checked">
        </p>


        <p> 关注的模块:
            C <input type="checkbox" name="modular" value="C">
            Python <input type="checkbox" name="modular" value="Python">
            Linux <input type="checkbox" name="modular" value="Linux">
        </p>

        <p> 手机号码: <input type="number" name="phone"></p>
        <p> 生日: <input type="date" name="birthday"></p>
        <p> 邮箱: <input type="email" name="email"></p>
        <p> 主页地址: <input type="url" name="my_url"></p>
        <p> 主题颜色: <input type="color" name="color"></p>

        <p>
            所在城市:
            <select name="city">
                <option value="A">A城市</option>
                <option value="B">B城市</option>
            </select>
        </p>

        <P>
            开通会员:
            <select name="member">
                <optgroup label="按年">
                    <option value="one_year">一年</option>
                    <option value="teo_year">两年</option>
                </optgroup>

                <optgroup label="按月">
                    <option value="one_mouth">一个月</option>
                    <option value="two_mouth">两个月</option>
                </optgroup>
            </select>
        </P>

        <p>
            <input type="submit" value="注册">
            <input type="reset" value="清空">
        </p>
    </fieldset>
</form>

</body>
</html>
handlebars 复制代码
提交的数据(特殊字符会被转换为十六进制格式: %XX):
username=kid&password=123&avatar=%E4%B8%8B%E8%BD%BD.jpg&info=hello+world%21&gender=secrecy&
modular=C&phone=12345678910&birthday=2023-0802&email=136%40qq.com&
my_url=https%3A%2F%2Fwww.hello.com&color=%231410ea&city=A&member=one_year

11.2 Flask服务端程序

handlebars 复制代码
* 1. 先安装FLASK框架: pip install falsk .
handlebars 复制代码
* 2. 用Flask框架创建一个简单的Web应用程序并运行它.

     2.1 首先, 导入Flask类, 这是Flask框架的核心类, 用于创建Flask应用程序.
     
     2.2 接下来, 创建一个名为app的Flask对象, 通过Flask(__name__)进行实例化.
         __name__参数是一个特殊的Python变量, 它表示当前模块的名称.
         在应用程序中, 它通常是一个特定的值, 用于帮助Flask找到静态文件和模板文件的位置.

     2.3 然后, 调用app.run()方法来运行应用程序.
         这个方法会启动一个本地的开发服务器, 它会监听HTTP请求并将它们传递给我们的应用程序处理.
         默认情况下, 应用程序将在localhost(即本地主机)上监听端口号为5000的请求.
         可以通过指定其他参数来自定义服务器的行为, 例如绑定到不同的主机或使用不同的端口.
python 复制代码
# flask_server.py
from flask import Flask

app = Flask(__name__)

app.run()
handlebars 复制代码
* 3. 在浏览器中访问http://127.0.0.1:5000/, 访问Flask应用程序的根目录(/).
handlebars 复制代码
这些日志信息是在运行Flask应用程序时生成的.
- 第一行日志显示了客户端的IP地址(127.0.0.1)以及请求的详细信息(GET / HTTP/1.1), 这表示客户端向根路径发起了一个GET请求.
- 第二行日志显示了客户端的IP地址和请求的详细信息(GET /favicon.ico HTTP/1.1), 其中favicon.ico表示浏览器请求网站的favicon图标.
  这个请求通常会在浏览器窗口的标签页上显示网站的图标.

然后, 每一行的最后是响应的状态码.
在日志中, 都是404状态码. 这表示请求的资源没有被找到, 即所请求的URL在应用程序中没有匹配的路由.

根据日志信息, 可以看出应用程序返回了404错误页面.
handlebars 复制代码
* 4. 修复问题, 要确保在应用程序中定义了处理根路径(/)和favicon.ico请求的路由函数.
     可以通过创建一个视图函数并使用Flask的装饰器方式来实现, 例如: 
python 复制代码
# flask_server.py
import os
from flask import Flask, send_from_directory

app = Flask(__name__)


# 当访问根路径 / 时, 会执行下方定义的 index 函数.
@app.route('/')
def index():
    # 访问根目录返回的提示信息.
    return 'Hello, Flask!'


# 当访问 /favicon.ico 路径时, 会执行下方定义的 favicon 函数.
@app.route('/favicon.ico')
def favicon():
    # 返回favicon图标.
    return send_from_directory('static', 'favicon.ico')


if __name__ == '__main__':
    app.run()
handlebars 复制代码
send_from_directory的函数, 用于从指定的目录中发送文件.
send_from_directory函数接收两个参数: 目录路径和文件名.
在代码根目录下创建一个名为static的子目录, 并将favicon.ico图标文件放置在其中(自己随便找一张32*32像素的照片).
这样, 当访问 /favicon.ico 路径时, Flask 将发送该图标文件作为响应.
handlebars 复制代码
* 5. 设置html数据的提交地址, <form action="http://127.0.0.1:5000"> .
* 6. 在注册界面输入注册信息, 写完后点击提交.

11.3 前端页面请求

handlebars 复制代码
前端页面请求: 是指前端开发中对服务器发起的HTTP请求.
当用户在浏览器中访问一个网页时, 浏览器会发送请求到服务器, 请求获取网页的内容和资源.
这些请求包括获取HTML, CSS, JavaScript文件, 图片等静态资源, 以及与服务器进行交互的动态请求, 如从服务器获取数据或提交表单等操作.

常见的前端页面请求包括:
* 1. GET请求: 用于获取指定资源, 例如获取网页内容, 获取图片, 获取数据等.
* 2. POST请求: 用于向服务器提交数据, 例如提交表单数据, 向服务器发送用户评论等.
...

在进行前端页面请求时, 开发者需要考虑安全性和性能等因素, 合理地选择合适的请求方式, 并进行错误处理和异常处理, 以提供良好的用户体验.
handlebars 复制代码
GET请求特点: 通过在URL中传递参数.
form表单默认提交数据的方式是get请求, 数据是直接放在url后面的.
handlebars 复制代码
POST请求特点: 通过请求体发送数据.
form表单的method属性指定表单的提交方式, 默认为get, 现在指定为post方式提交表单.
html 复制代码
<form action="http://127.0.0.1:5000" method='post'> 
handlebars 复制代码
后端代码中, 在装饰器@app.route('/')中设置methods参数支持post请求: @app.route('/', methods=['GET', 'POST']) .
默认不写就只能接受get请求, 设置后支持get请求也可以支持post请求.

11.4 获取表单数据

handlebars 复制代码
在Flask中, 可以使用request.form来获取通过POST请求提交的表单数据(不含文件类型数据).
request.form是一个特殊的字典对象, 它提供了一种访问表单数据的方式, 其中表单字段名作为键, 对应的值为用户在表单中输入的数据.
request.form.get(名称)方法: 获取表单字段的值(只有在前端构造了名称-值的数据可以被拿到).
python 复制代码
# flask_server.py
import os
from flask import Flask, send_from_directory, request

app = Flask(__name__)


@app.route('/', methods=['GET', 'POST'])
def index():
    # 获取表单数据.
    print(request.form)
    # 获取username字段对应的值.
    print(request.form.get('username'))
    # 获取password字段对应的值.
    print(request.form.get('password'))
    return 'Hello, Flask!'


@app.route('/favicon.ico')
def favicon():
    return send_from_directory('static', 'favicon.ico')


if __name__ == '__main__':
    app.run()
handlebars 复制代码
在前端提交数据, 在后端查看运行结果:
ImmutableMultiDict([('username', 'kid'), ('password', '123'), ('avatar', '下载.jpg'), ('info', 'hello world!'), 
('gender', 'secrecy'), ('modular', 'C'), ('phone', '123456789'), ('birthday', '2023-08-03'), ('email', '136@qq.com'), ('my_url', 'https://www.hello.com'), ('color', '#3904fb'), ('city', 'A'), ('member', 'one_year')])
kid
123
handlebars 复制代码
ImmutableMultiDict是一个不可变多值字典的对象, 常用于处理HTTP请求中的表单数据.
它是一种特殊类型的字典, 支持一个键对应多个值的情况.

11.4 提交与获取文件

handlebars 复制代码
想要在表单中提交文件时, 需要满足以下两个条件:

* 1. method="post": 这是表单的提交方法之一, 用于指定提交表单数据的HTTP请求类型为POST.
     相比于GET方法, POST方法可以发送更大容量的数据, 并且更适合用于上传文件.

* 2. enctype="multipart/form-data": 这是用于指定表单数据编码格式的属性.
     当enctype属性的值设置为multipart/form-data时, 表单将使用多部分(multipart)编码格式来提交数据, 可以包含二进制文件数据.

这两个条件一起使用, 可以实现在表单中提交文件数据.
对于纯文本数据, 可以使用默认的application/x-www-form-urlencoded编码格式.
但是如果包含文件数据, 就需要使用multipart/form-data编码格式来确保文件正确地被提交.
html 复制代码
<!-- 修改enctype属性值 -->
<form action="http://127.0.0.1:5000" method="post" enctype="multipart/form-data">
handlebars 复制代码
request.files方法: 用于获取用户通过表单上传的文件.

常用的request.files方法和属性:

request.files.get('file_field'): 返回给定文件字段名称的文件对象. 如果找不到该字段, 则返回None.

request.files['file_field']: 返回给定文件字段名称的文件对象. 如果找不到该字段, 则引发KeyError异常.

request.files.keys(): 返回一个包含所有文件字段名称的视图对象.

request.files.values(): 返回一个包含所有文件对象的视图对象.

request.files.items(): 返回一个包含所有文件字段名称和文件对象的元组视图对象.

file_object.filename: 文件对象的原始文件名.

file_object.save(filepath): 将文件保存到指定的文件路径.
handlebars 复制代码
 注意点: 前端页面与后端服务端中保存的文件名称要相同, 不然会报错.
 name="file.png"                            # html中输入框的名字.
 file_obj = request.files.get('file.png')   # py文件中通过这个名称获取文件对象.
python 复制代码
# flask_server.py
import os
from flask import Flask, send_from_directory, request

app = Flask(__name__)


@app.route('/', methods=['GET', 'POST'])
def index():
    # 获取表单数据.
    # print(request.form)
    # 获取username字段对应的值.
    # print(request.form.get('username'))
    # 获取password字段对应的值.
    # print(request.form.get('password'))

    # 获取文件数据.
    print(request.files)
    # 遍历字典.
    for key in request.files.keys():
        # 通过key获取值(文件对象).
        file_obj = request.files.get(key)
        # 保存文件.
        file_obj.save(file_obj.filename)
    return 'Hello, Flask!'

    return 'Hello, Flask!'


@app.route('/favicon.ico')
def favicon():
    # 返回favicon图标, 自己找一张图片命名为favicon.ico, 复制到项目的根目录下.
    return send_from_directory('static', 'favicon.ico')


if __name__ == '__main__':
    app.run()
相关推荐
理想不理想v8 分钟前
vue经典前端面试题
前端·javascript·vue.js
不收藏找不到我9 分钟前
浏览器交互事件汇总
前端·交互
。puppy17 分钟前
HCIP--3实验- 链路聚合,VLAN间通讯,Super VLAN,MSTP,VRRPip配置,OSPF(静态路由,环回,缺省,空接口),NAT
运维·服务器
YBN娜23 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=23 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
颇有几分姿色27 分钟前
深入理解 Linux 内存管理:free 命令详解
linux·运维·服务器
minDuck28 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。1 小时前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼1 小时前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui