Skip to content

表单

元信息

  • 目标:理解表单是前后端第一次握手——浏览器由此从"拉取 pull"转为"推送 push"数据;走完领取→填写→提交→后端检查→存库/退回的最小完整闭环,理解前后端分工的本质
  • 关键概念:表单form、action、method、GET/POST、enctype、后端脚本、重定向
  • 关联阶段:cp1
  • 常见误区:提交后跳出文件下载或 405 就懵(服务器不支持 php,把 save.php 当附件或报错返回——本地跑需 xampp);以为提交不是 HTTP 请求(提交就是 post 到 action 地址的一个请求,浏览器随后显示该响应);删除等写操作表单用 GET(搜索引擎等客户端会自动触发所有 GET 链接,带来严重后果)

什么是表单?

表单 form :是用于提交信息的机制,它可以实现浏览器向服务器推送(push)数据,写入信息

之前所学习的前端技术,都是浏览器从Web服务器拉取(pull)数据,读取信息

虚拟世界是对现实世界的模拟,但又不是简单的模拟

线下办事流程

  1. 申请人来到行政楼办事大厅,从1号窗口处 请求领取 一个申请表
  2. 填写 申请表上的各种选项
  3. 将申请表 递交 至2号窗口,该窗口工作人员 检查 申请表填写是否合格:
    • 合格则将申请表 存入 档案库。并 告知 申请者等待后续审批结果的通知
    • 如不合格,将申请表 返还 申请者,指出错误,由申请者再次_填写_后提交,直至合格。

线上办事流程

  1. 申请人进入办事网站首页,在浏览器中 点击敲入 一个申请链接(http"//x.com/new.html),领取 一个表单页面
  2. 填写 该表单页面上各种选项
  3. 点击提交,即将该页面 发送 到一个处理该页面的地址(http://x.com/save.php), 该php脚本文件 检查 申请表填写是否合格:
    • 如合格则将申请表 存入 数据库,并跳转至下一页面,并 告知 申请者等待后续审批结果的通知
    • 如不合格,跳转回 到表单页面,提示错误,由申请请再次 填写 后提交,直至合格。

流程对比

线下流程线上流程
到指定窗口领取表格访问指定url拉取表单
用纸笔填写表格用键鼠填写表单
按表格上的提示将表格交到指定窗口提交表单(浏览器自动提交到指定后端脚本地址)
填写错误,被窗口退回填写错误,被后端脚本退回
填写正确,离开窗口(或提示其它操作)填写正确,跳转到其它页面

不妨假想浏览器的后面藏着一个程序员,他接收你的提交的表单页面,然后返回包含有正确或错误信息的页面。当然,将来我们学习了Web后端编程,就知道这都是php等服务端脚本的功劳。

表单 <form>

<!DOCTYPE html>
<html>
<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
  <link rel="stylesheet" href="/styles.css" />
</head>
<body>
  <h1>Hello world</h1>
</body>
</html>
步骤行为标记与属性
领取表单+ 用户点击链接或键入地址 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接收表单的后端地址,格式同超链接
methodGET 或 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属性

<!DOCTYPE html>
<html>
<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
  <link rel="stylesheet" href="/styles.css" />
</head>
<body>
  <h1>Hello world</h1>
</body>
</html>

当你点击提交时,请注意浏览器地址栏的变化,即类似: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 重定向

语法参考

扩展阅读