Skip to content

实训:表单及前后端交互

参考表单,基于 xampp 环境亲手搭一次完整的前后端交互:自己写一个表单页面(前端),配一个 PHP 回显脚本(后端),提交、观察、改坏、再修复。完成后应能回答:

  • Web 数据是如何读取和提交的?
  • 前端与后端是如何交互的?
  • 前端页面和后端脚本之间是什么关系?

准备:确认环境

  1. XAMPP 已安装且 Apache 能启动(见XAMPP 教程
  2. 已配置一个虚拟站点(见虚拟站点),下文以 form.x.com 为例,站点目录为 htdocs/form。没有配置虚拟站点的话,直接用 htdocs/formhttp://localhost/form/ 访问也可以
  3. 浏览器打开 http://httpbin.org/forms/post 留着对照——它是本实训的"标准答案"演示页

第 1 步:编写前端表单页面

在站点目录 htdocs/form 下新建 form.html

<!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>

要点:每个输入控件都有 name 属性——它是数据提交时的"字段名",没有 name 的控件不会被提交。action 指向后端地址,method 指定 HTTP 动词。

第 2 步:编写后端脚本

同目录下新建 save.php(即表单中的回显脚本):

php
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>提交结果</title></head>
<body>
<h3>服务器收到以下数据:</h3>
<ol>
<?php
  foreach ($_POST as $key => $value){
    echo "<li>{$key} : {$value}</li>";
  }
?>
</ol>
<a href="./form.html">返回表单</a>
</body>
</html>

注意:.php 文件和 .html 文件放在同一目录——它们是同一站点里的两个页面,一个负责采集,一个负责处理。

第 3 步:提交并观察

  1. 浏览器访问 http://form.x.com/form.html(或 http://localhost/form/form.html

  2. 修改输入框内容,点击"提交留言"

  3. 应看到 save.php 返回的列表:nickname : 你填的值message : ...channel : ...

  4. 按 F12 打开 devtools → Network(网络)面板,找到 save.php 这条请求,查看:

    • Payload/表单数据:你提交的字段名和值
    • Response(响应):服务器返回的 HTML——正是你现在看到的页面

    这一步是本实训的核心:亲眼确认"提交 = 一个 POST 请求",请求和响应都是完整的 HTTP 报文。

第 4 步:改成 GET,对比观察

form.htmlmethod="post" 改为 method="get"(save.php 中的 $_POST 也要改为 $_GET),再次提交,观察三处变化:

  1. 地址栏:变成了 save.php?nickname=tom&message=...——数据跑到了 URL 查询字符串里
  2. devtools:请求的 Payload 不再有请求体,数据在 URL 上
  3. 刷新页面:GET 提交后刷新会重复请求(幂等),POST 刷新会弹出"重新提交表单?"警告——这就是两者语义区别的直观体现

结论对照表单中 GET/POST 的对比表:GET 数据在 URL、语义只读;POST 数据在报文体、语义写入。

第 5 步:把后端"改坏",理解依赖关系

依次做三个破坏性实验,每次改完刷新或重新提交:

  1. 改掉 action:把 action="./save.php" 改为不存在的 ./savex.php,提交——得到 404。说明前端表单依赖后端地址真实存在
  2. 把 save.php 改名为 save.txt,提交——浏览器可能把文件当附件下载。原因:Apache 只把 .php 交给 PHP 引擎执行,其他扩展名按普通文件直接返回(见表单中的错误分析)
  3. 停掉 Apache(XAMPP 面板 Stop),访问表单——整个站点都不可达。说明前端页面本身也是从服务器获取的

三个实验共同回答"前端页面和后端脚本之间的关系":同属一个站点、通过 HTTP 的一问一答协作、任何一环断裂交互即失败

第 6 步(选做):让后端真正"记住"数据

把 save.php 的 PHP 部分改为写入文件,模拟一次真正的"存储":

php
<?php
  $file = fopen("db.txt", "a");
  foreach ($_POST as $key => $value){
    fputs($file, "{$key} : {$value}\n");
  }
  fclose($file);
  echo "<p>留言已保存,<a href='./db.txt'>查看数据文件</a></p>";
?>

提交几次后打开 db.txt:数据已经持久化在后端磁盘上。注意这里用了 "a"(追加)模式而不是 "w"(覆盖)。这就是"后端处理"的最小实例——真实站点无非是把 db.txt 换成数据库。

验收标准

  • [ ] form.html 与 save.php 部署在本地站点,GET/POST 两种方式提交成功
  • [ ] 能在 devtools 中指出一次表单提交的请求方法、URL、负载数据与响应内容
  • [ ] 完成第 5 步的三个破坏性实验,并能解释每个现象
  • [ ] (选做)db.txt 能累积保存多次提交

思考

  • 提交后地址栏变成 save.php——"当前页面"是谁生成的?前端还是后端?
  • 如果表单里有个输入框没写 name 属性,后端能收到它的数据吗?为什么?
  • 搜索框表单应该用 GET 还是 POST?(提示:见表单"正确地使用语义"一节)