Appearance
表单
元信息
- 目标:理解表单是前后端第一次握手——浏览器由此从"拉取 pull"转为"推送 push"数据;走完领取→填写→提交→后端检查→存库/退回的最小完整闭环,理解前后端分工的本质
- 关键概念:表单form、action、method、GET/POST、enctype、后端脚本、重定向
- 关联阶段:cp1
- 常见误区:提交后跳出文件下载或 405 就懵(服务器不支持 php,把 save.php 当附件或报错返回——本地跑需 xampp);以为提交不是 HTTP 请求(提交就是 post 到 action 地址的一个请求,浏览器随后显示该响应);删除等写操作表单用 GET(搜索引擎等客户端会自动触发所有 GET 链接,带来严重后果)
什么是表单?
表单 form :是用于提交信息的机制,它可以实现浏览器向服务器推送(push)数据,写入信息
之前所学习的前端技术,都是浏览器从Web服务器拉取(pull)数据,读取信息
虚拟世界是对现实世界的模拟,但又不是简单的模拟
线下办事流程
- 申请人来到行政楼办事大厅,从1号窗口处 请求 和 领取 一个申请表
- 填写 申请表上的各种选项
- 将申请表 递交 至2号窗口,该窗口工作人员 检查 申请表填写是否合格:
- 合格则将申请表 存入 档案库。并 告知 申请者等待后续审批结果的通知
- 如不合格,将申请表 返还 申请者,指出错误,由申请者再次_填写_后提交,直至合格。
线上办事流程
- 申请人进入办事网站首页,在浏览器中 点击 或 敲入 一个申请链接(
http"//x.com/new.html),领取 一个表单页面 - 填写 该表单页面上各种选项
- 点击提交,即将该页面 发送 到一个处理该页面的地址(
http://x.com/save.php), 该php脚本文件 检查 申请表填写是否合格:- 如合格则将申请表 存入 数据库,并跳转至下一页面,并 告知 申请者等待后续审批结果的通知
- 如不合格,跳转回 到表单页面,提示错误,由申请请再次 填写 后提交,直至合格。
流程对比
| 线下流程 | 线上流程 |
|---|---|
| 到指定窗口领取表格 | 访问指定url拉取表单 |
| 用纸笔填写表格 | 用键鼠填写表单 |
| 按表格上的提示将表格交到指定窗口 | 提交表单(浏览器自动提交到指定后端脚本地址) |
| 填写错误,被窗口退回 | 填写错误,被后端脚本退回 |
| 填写正确,离开窗口(或提示其它操作) | 填写正确,跳转到其它页面 |
不妨假想浏览器的后面藏着一个程序员,他接收你的提交的表单页面,然后返回包含有正确或错误信息的页面。当然,将来我们学习了Web后端编程,就知道这都是php等服务端脚本的功劳。
表单 <form>
| 步骤 | 行为 | 标记与属性 |
|---|---|---|
| 领取表单 | + 用户点击链接或键入地址 form.html<br/>+ 浏览器 http get form.html 从服务器 | <form>标记与action,method,enctype等属性 |
| 填写表单 | 用户填写form.html中的各个字段 | <input type="text"> 文本控件标记 |
| 提交表单 | + 用户点击提交<br/>+ 浏览器将表单内容打包 http post to save.php | <input type="submit" /> 提交控件标记 |
运行save.php需要php环境,故请下载save.php(注意和form.html放至于同一目录)至本地的xampp环境后再运行。或者使用 httpbin 的表单演示页面,观察返回的结果。
- 如果服务器不支持php,服务端会返回报错信息:405 not allowed ! 其中405是http状态码,还记得http状态码网站吗 http://httpstatusdogs.com/
关键属性
| 属性名 | 属性值 | 说明 |
|---|---|---|
| action | ./code/save.php | 接收表单的后端地址,格式同超链接 |
| method | GET 或 POST | 以何种HTTP方式将表单数据发送给后端 |
| enctype | 默认为 application/x-www-form-urlencoded | 如果表单中包含二进制数据即附件,则必须为 multipart/form-data |
后端脚本
php
<body>
<?php
foreach ($_POST as $key => $value){echo "<li>{$key} : {$value} </li>";}
?>
</body>save.php是一个php语言编写的后端脚本,这里出于演示的目的,仅仅是将浏览器发过来的表单的值进行回显,而不是保存在后端的数据库或磁盘中。此段脚本中:
- $_POST变量是php引擎提供的特殊变量,它总是保存着表单发送过来的数据
$key对应于表单输入控件的名字,即<input name='login'>的 name 属性的值$value对应于表单输入控件的值,即<input value='tom'>的 value 属性的值- save.php本质上仍是一个html页面,或者是php代码总是嵌入在html页面中运行
- 一般情况下,即使你不书写任何html标记,服务端总是将php脚本运行的结果包装为一个html页面,然后返回给浏览器
表单提交后发生了什么?
- 提交也是一个http请求,请求的url为save.php,相当于浏览器当前将显示save.php这一页面
- 浏览器将表单中的字段数据,以post(method属性)的方式发送给save.php(action属性)
- 服务端的Apache服务器接收到数据,将数据转发给php执行引擎,引擎再转发给save.php
- 执行save.php代码,将其_执行结果_包装为一个html页面,作为响应返回给客户端
- 客户端浏览器收到响应,将返回的页面渲染给用户
记住: 浏览器发送的,称之为_请求_,服务器返回的,称之为_响应_,浏览器的所有工作可以简化为,发送一个请求,接收一个响应进行渲染,然后继续,周而复始
当 form 使用 method="get"
表单提交也可以采用http get方式,注意method属性
当你点击提交时,请注意浏览器地址栏的变化,即类似:http://x.com/save.php?text=七朵玫瑰花&selectd=信息安全 这样的地址。
这就是GET方式和POST的最显著区别,表单数据将被附加到URL的查询字符串进行传递
然而,浏览器的反应也可能是:跳出一个文件下载的提示! 然后你查看这个下载的文件,会发现它正是save.php的源代码。
错误的原因:仍然是如前所述,可能是服务器并不支持运行PHP,因此Web服务器会将这个php文件视作非html页面直接返回(如同返回文件附件一样)。同样,对于浏览器而言,它也不识别php这类文件格式或文档类型。因此,就如同处理其它二进制类型文件一样,将save.php作为一个普通的附件进行下载,交由用户来处理。
HTTP GET 与 HTTP POST
HTTP定义至少两种浏览器与Web服务器之间进行交互的方式,又称HTTP动词
| 动词类型 | 用户行为 | 数据流向 | 数据传输 |
|---|---|---|---|
| HTTP GET | 点击链接,地址栏中输入url等 | 服务端->客户端,语义只读,幂等操作 | 直接通过url中的查询字串 http://www.x.com/index.php?key=nba |
| HTTP POST | 必须通过表单 | 客户端 -> 服务端,语义写入 | 数据封装在http包里,可通过浏览器的 devtools 查看 |
正确地使用语义
- 在语义为post的场景下,比如新增、更改和删除等表单请求中,请务必使用http post,因为搜索引擎等第三方web 客户端,默认总是会访问和触发所有的http get请求,比如链接或表单页面。
- 如果你的删除表单使用了http get请求,可能会带来严重后果
- 有一类表单,比如设置搜索条件的表单,从语义上,应该使用http get,但有时表单过于复杂,也可能会使用http post;虽然违反了语义,但并不会造成恶劣的后果
思考
php
<?php
$file = fopen("db.txt","w");
foreach ($_POST as $key => $value){
fputs($file, "{$key} : {$value}\n");
}
fclose($file);
?>这个脚本将表单的内容存入服务器磁盘,从而可以在后续的请求中,再将文件内容读出返回给浏览器。
这个脚本令人迷惑的地方是:当你在浏览器端提交表单后,你将会看到一片空白的页面,这是为什么?
提示:当我们在各大社交站点登录成功后,我们会立即看到首页或个人中心页面,哪怕我们并没有在浏览器地址栏键入这些地址,这是因为社交站点的登录脚本会在用户表单提交正确后,发起一个http 重定向
- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Guides/Redirections
- https://www.cnblogs.com/wuguanglin/p/redirect.html
语法参考
- http://www.runoob.com/html/html-forms.html
- http://www.runoob.com/tags/html-httpmethods.html
- http://www.runoob.com/html/html5-form-attributes.html
扩展阅读
- HTTP POST GET 本质区别详解 http://blog.csdn.net/wuxiaobingandbob/article/details/52190704
- 观察和模拟各类form的操作 https://www.getpostman.com/
- HTTP GET/POST 请求参数长度 http://blog.csdn.net/jackpk/article/details/44305147
- enctype 详解 https://blog.csdn.net/ght886/article/details/79089718
- http 重定向 https://www.cnblogs.com/bq-med/p/8602629.html