多数时候,HTML表单的目的只是为了把数据发给服务器,之后服务器再处理这些数据并发送响应给用户。虽然看起来挺简单的,但我们还是得注意一些事情以确保传送的数据不会破坏服务器、或者给你的用户制造麻烦。
站在用户的角度思考问题,与客户深入沟通,找到庆云网站设计与庆云网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都网站建设 、成都网站制作、企业官网、英文网站、手机端网站、网站推广、域名申请 、网络空间、企业邮箱。业务覆盖庆云地区。
数据会到哪里去
关于客户端/服务器架构
整个web都是基于一种基本的客户端/服务器架构,该架构可以归纳如下:
一个客户端(通常是Web浏览器)使用HTTP协议发送一个请求给服务器(通常是web服务器程序,譬如Apache, Nginx, IIS, Tomcat等等),而服务器则以相同的协议响应这个请求。
在客户端,HTML表单只是提供一种比较方便且用户友好的方式,用来配置发送给服务器的HTTP请求。这样用户就可以自己提供能被HTTP请求传送的信息。
客户端:定义如何发送数据
使用GET方法时,HTTP请求看起来就这样:
GET /?say=Hi&to=Mom HTTP/1.1
Host: foo.com
POST方法
POST方法则稍有不同,浏览器发送这个方法给服务器,用以请求一个和HTTP请求体里数据有关的响应:“嘿服务器,看看这些数据然后给我发回一个适当的结果”。若表单使用该方法发送,则数据会给追加到HTTP请求体里。
示例
考虑如下表单(和上面那个一样):
Send my greetings
使用POST方法时,HTTP请求看起来就这样:
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字段则标识了发往服务器的资源类型。我们将在稍后讨论下这些请求头。
当然,HTTP请求是不会展示给用户看的(若你想看到它们,还得使用诸如火狐的Web Console或者chrome Developer Tools等工具),唯一展示给用户的,只有访问的URL。所以使用GET请求时,用户将会在他们的地址栏看到数据,而使用POST请求则看不到。这点至关重要,原因如下:
若你要发送密码(或者任何敏感数据),那千万别用GET方法,否则该数据会不安全地展示在地址栏上。
若你想要发送大量数据,最好用POST方法,因为一些浏览器会限制URL的大小。此外,许多服务器也会限制接收的URL长度。
服务器端:处理数据
不论你选择哪种HTTP方法,服务器只会接收到一个字符串并将其解析,再以键/值对列表的形式获取数据。而如何访问这个列表,取决于你基于何种开发平台、以及用了何种框架。你使用的技术也会决定如何处理重复的键名,通常某个键名最后接收到的值是优先被选取的。
示例:原生PHP
PHP提供了几个全局对象来处理数据。假设你使用POST方法,下面的示例会直接提取你的数据并展示给用户。当然,要如何处理数据取决于你,你可以展示它、将其存进数据库、用邮件发送它、或者其他任何方式。
// 全局变量$_POST让你能够访问用POST方法发送的数据
// 要访问用GET方法发送的数据,可以使用$_GET
$say = htmlspecialchars($_POST['say']);
$to = htmlspecialchars($_POST['to']);
echo $say, ' ', $to;
这个示例会用我们发送的数据生成一个页面。考虑我们前面用的表单示例数据,输出结果会是:
Hi Mom
示例:原生Python
下面的示例使用Python来做相同的事---将给定的数据展示到web页面上。其中使用了CGI Python package 来处理表单数据。
#!/usr/bin/env python
import html
import cgi
import cgitb; cgitb.enable() # 用于处理错误
print("Content-Type: text/html") # 请求头字段,标识后面的内容是HTML
print() # 空行,表示请求头的结束
form = cgi.FieldStorage()
say = html.escape(form["say"].value);
to = html.escape(form["to"].value);
print(say, " ", to)
结果和之前用PHP处理是一样的:
Hi Mom
其它语言和框架
还有许多其他的服务端技术可以用来处理表单,比如Perl, Java, .Net, Ruby等等,选择你最喜欢的一种就好。我们很少直接使用这些技术,因为这么做得需要很多技巧来填坑;通常我们会在众多好用的框架中选择一种,这样会让表单的处理更容易些,比如:
Symfony for PHP
Django for Python
Ruby On Rails for Ruby
Grails for Java
值得注意的是,就算用了这些框架,处理表单是不一定就会变得轻松。但至少这样用起来会更好些,还能节省你不少时间。
特殊案例:发送文件
文件是HTML表单中一个特殊的例子,其他数据都是文本数据,而文件则一般是、或者被认为是二进制数据。由于HTTP是个文本协议,所以对处理二进制数据得有特别的要求。
enctype特性
该特性能让你指定HTTP请求头中的Content-Type字段值,这个字段的重要性在于,它能告诉服务器要发送的数据类型。其默认值是application/x-www-form-urlencoded,对应的解释是:“这份表单数据已被编码为URL格式”。
而当你想发送文件时,得先做两件事:
将method特性设置为POST,因为使用表单时,文件内容是不能被放到URL参数里的
将enctype特性的值设为multipart/form-data,这样数据就会被分割为多个部分,每个文件都会追加上和他们一起发送的表单有关的文本。
示例:
Send the file
注意:某些浏览器支持 元素的multiple特性,以便让一个input元素能发送多个文件。至于服务器会如何处理这些文件,就得取决于它用来什么技术了。如前所述,使用框架能让你的活的轻松些~
警告:为防止滥用,许多服务器会对文件和HTTP请求设置大小限制。所以,最好在发送文件之前和服务器管理员核实一下这个限制。
安全相关
每次要发数据给服务器前,你都得考虑下安全问题。HTML表单是针对服务器的首要攻击载体之一,但该危害的来源并非HTML表单本身,而在于服务器如何处理数据。
常见的安全问题
著名的安全问题有很多,如何划分取决于你在做什么:
XSS和CSRF
跨站脚本攻击(XSS)和跨站请求伪造(CSRF)是最常见的攻击类型,它们会在你展示由用户发给用户的数据时发生。
XSS让攻击者能再其他用户访问的Web页面上注入客户端脚本。攻击者会利用跨站脚本的脆弱性来绕过访问控制策略,譬如同源策略。这种攻击可以取得从小麻烦到严重安全危机不等的危害效果。
CSRF很像XSS,因为它们都以相同的方式开始---注入客户端脚本到Web页面,但它们的攻击目标却不同。CSRF攻击者会试着升级权限以成为一个高权限的用户(比如网站管理员),然后执行本不能够执行的动作(如把数据发送给不受信任的用户)。
XSS攻击利用了用户对网站的信任,而CSRF攻击则利用了网站对其用户的信任。
要防止此类攻击,就得时常校验用户发送给服务器的数据;同时(如果需要展示)也尽量别展示用户提供的HTML内容,而应该处理用户提供的数据,以避免将其原封不动地显示出来。目前几乎所有市面上的的框架,至少都会实现一个过滤器,用以移除用户提交数据中
基本
文件
流程
错误
SQL
调试
请求信息 : 2026-02-22 18:16:41 HTTP/1.1 GET : /article/cdgoggg.html 运行时间 : 0.0639s ( Load:0.0034s Init:0.0006s Exec:0.0556s Template:0.0044s ) 吞吐率 : 15.65req/s 内存开销 : 2,250.64 kb 查询信息 : 12 queries 5 writes 文件加载 : 36 缓存信息 : 0 gets 2 writes 配置加载 : 130 会话信息 : SESSION_ID=cvvvglfdahanjr5hcjj5ulsrt2
/home/wwwroot/jxjierui.cn/index.php ( 1.12 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/ThinkPHP.php ( 4.61 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Think.class.php ( 12.26 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Storage.class.php ( 1.37 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Storage/Driver/File.class.php ( 3.52 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Mode/common.php ( 2.82 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Common/functions.php ( 53.56 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Hook.class.php ( 4.01 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/App.class.php ( 13.49 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Dispatcher.class.php ( 14.79 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Route.class.php ( 13.36 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Controller.class.php ( 11.23 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/View.class.php ( 7.59 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php ( 3.68 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Behavior/ParseTemplateBehavior.class.php ( 3.88 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php ( 1.91 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Conf/convention.php ( 11.15 KB ) /home/wwwroot/jxjierui.cn/App/Common/Conf/config.php ( 2.12 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Lang/zh-cn.php ( 2.55 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Conf/debug.php ( 1.48 KB ) /home/wwwroot/jxjierui.cn/App/Home/Conf/config.php ( 0.32 KB ) /home/wwwroot/jxjierui.cn/App/Home/Common/function.php ( 3.33 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Behavior/ReadHtmlCacheBehavior.class.php ( 5.62 KB ) /home/wwwroot/jxjierui.cn/App/Home/Controller/ArticleController.class.php ( 6.11 KB ) /home/wwwroot/jxjierui.cn/App/Home/Controller/CommController.class.php ( 1.60 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Model.class.php ( 60.11 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Db.class.php ( 32.43 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Db/Driver/Pdo.class.php ( 16.74 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Cache.class.php ( 3.83 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Cache/Driver/File.class.php ( 5.87 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Template.class.php ( 28.16 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Template/TagLib/Cx.class.php ( 22.40 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Template/TagLib.class.php ( 9.16 KB ) /home/wwwroot/jxjierui.cn/App/Runtime/Cache/Home/7540f392f42b28b481b30614275e4e55.php ( 13.96 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php ( 0.97 KB ) /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Behavior/ShowPageTraceBehavior.class.php ( 5.24 KB )
[ app_init ] --START-- Run Behavior\BuildLiteBehavior [ RunTime:0.000005s ] [ app_init ] --END-- [ RunTime:0.000025s ] [ app_begin ] --START-- Run Behavior\ReadHtmlCacheBehavior [ RunTime:0.000161s ] [ app_begin ] --END-- [ RunTime:0.000175s ] [ view_parse ] --START-- [ template_filter ] --START-- Run Behavior\ContentReplaceBehavior [ RunTime:0.000050s ] [ template_filter ] --END-- [ RunTime:0.000067s ] Run Behavior\ParseTemplateBehavior [ RunTime:0.003469s ] [ view_parse ] --END-- [ RunTime:0.003485s ] [ view_filter ] --START-- Run Behavior\WriteHtmlCacheBehavior [ RunTime:0.000064s ] [ view_filter ] --END-- [ RunTime:0.000076s ] [ app_end ] --START--
1064:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') LIMIT 1' at line 1
[ SQL语句 ] : SELECT `id`,`pid`,`navname` FROM `cx_nav` WHERE ( id= ) LIMIT 1 1064:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') LIMIT 1' at line 1
[ SQL语句 ] : SELECT `id`,`navname` FROM `cx_nav` WHERE ( id= ) LIMIT 1 1064:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
[ SQL语句 ] : SELECT `id`,`navname` FROM `cx_nav` WHERE ( pid= ) [8] Undefined index: pid /home/wwwroot/jxjierui.cn/App/Home/Controller/ArticleController.class.php 第 47 行. [2] file_put_contents(./App/Runtime/Temp/ee06ff49703224da19e4e9ea6be60e8d.php): failed to open stream: Permission denied /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Cache/Driver/File.class.php 第 132 行. [8] Undefined index: db_host /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Db.class.php 第 120 行. [8] Undefined index: db_port /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Db.class.php 第 121 行. [8] Undefined index: db_name /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Db.class.php 第 122 行. [2] file_put_contents(./App/Runtime/Temp/b06ce919f773eed5678c081984589d79.php): failed to open stream: Permission denied /home/wwwroot/jxjierui.cn/ThinkPHP/Library/Think/Cache/Driver/File.class.php 第 132 行.
0.0639s