【发布时间】:2011-03-26 09:19:54
【问题描述】:
我有一个 PHP 脚本会动态生成 <input>s,所以我想知道是否需要过滤 name 属性中的任何字符。
我知道名字必须以字母开头,但是我不知道其他规则。我认为必须允许使用方括号,因为 PHP 使用它们从表单数据创建数组。括号呢?空间?
【问题讨论】:
标签: html forms web-standards html-input
我有一个 PHP 脚本会动态生成 <input>s,所以我想知道是否需要过滤 name 属性中的任何字符。
我知道名字必须以字母开头,但是我不知道其他规则。我认为必须允许使用方括号,因为 PHP 使用它们从表单数据创建数组。括号呢?空间?
【问题讨论】:
标签: html forms web-standards html-input
请注意,并非所有字符都为表单字段的name 属性提交(即使使用 POST)!
空白字符被修剪,内部空白字符以及字符. 被_ 替换。
(在 Chrome 23、Firefox 13 和 Internet Explorer 9 中测试,所有版本均为 Win7。)
【讨论】:
first[second] 而不是 first.second。
您可以在 [X]HTML 文件中包含的任何字符都可以放入 <input name>。正如 Alllain 的评论所说,<input name> 被定义为包含 CDATA,因此您唯一不能放入的内容是底层标准(SGML 或 XML)不允许的控制代码和无效代码点。
Allain 引用了 HTML4 规范中的 W3:
注意。 “get”方法将表单数据集值限制为 ASCII 字符。只有“post”方法(enctype="multipart/form-data")被指定覆盖整个 ISO10646 字符集。
然而这在实践中并不是真的。
理论上,application/x-www-form-urlencoded 数据没有为表单名称或值指定编码的机制,因此在任何一个中使用非 ASCII 字符都“未指定”为有效,您应该使用 POSTed @987654327 @ 代替。
不幸的是,在现实世界中,即使理论上可以,也没有浏览器在 multipart/form-data POST 请求正文的子部分标头中为字段指定编码。 (我相信 Mozilla 曾经尝试过实现它,但因为它破坏了服务器而退出了。)
并且没有浏览器实现了将编码的非 ASCII 字段名称插入到多部分的子部分标头中所必需的极其复杂和丑陋的 RFC2231 标准。无论如何,定义multipart/form-data 的 HTML 规范并没有直接说应该使用 RFC2231,而且,如果你尝试过,它会再次破坏服务器。
因此,实际情况是,无论是什么类型的表单,都无法知道表单提交中的名称和值使用什么编码。对于 GET 和两种类型的 POST 表单,浏览器对包含非 ASCII 字符的字段名称和值的处理方式是相同的:它使用包含所用表单的页面的编码对它们进行编码。非 ASCII GET 表单名称不会比其他所有内容都更坏。
DLH:
所以 name 的数据类型与其他元素的数据类型不同?
实际上,name 属性不是CDATA 的唯一元素是<meta>。请参阅 HTML4 规范的 attribute list 了解 name 的所有不同用途;它是一个重载的属性名称,对不同的元素有许多不同的含义。这通常被认为是一件坏事。
但是,现在您通常会避免使用 name,除非在表单字段(它是控件名称)和 param(它是特定于插件的参数标识符)上。这只是要解决的两个含义。应避免使用老式的name 来识别页面上的<form> 或<a> 等元素(改用id)。
【讨论】:
【讨论】:
name 对<input> 的数据类型与对其他元素的数据类型不同?很有趣。
<a>和大多数元素相同,但与<meta>不同
name 属性中尝试了带有各种废话的<input>,并在HTML 4.01 Strict 中进行了验证。接受!
虽然艾伦的评论确实回答了 OP 的直接问题,并且 bobince 提供了一些精彩的深入信息,但我相信很多人来这里寻求更具体问题的答案:“我可以在表单的输入名称属性中使用点字符吗?”
当我搜索此知识时,由于此线程作为第一个结果出现,我想我不妨分享一下我发现的内容。
首先,Matthias 声称:
字符。替换为_
这是不真实的。我不知道浏览器是否真的在 2013 年做过这种操作——不过,我对此表示怀疑。浏览器按原样发送点字符(谈论 POST 数据)!您可以在任何不错的浏览器的开发者工具中查看它。
请注意 abluejelly 的那条小小的评论,可能很多人都错过了:
我想指出,这是特定于服务器的事情,而不是浏览器的事情。在 Win7 FF3/3.5/31、IE5/7/8/9/10/Edge、Chrome39 和 Safari Windows 5 上测试,它们都将“test this.stuff”(四个前导空格)作为 POST 中的名称发送到与 VS2012 捆绑的 ASP.NET 开发服务器。
我用 Apache HTTP 服务器(v2.4.25)检查了它,确实输入名称如“foo.bar”已更改为“foo_bar”。但是在像“foo[foo.bar]”这样的名称中,点不会被_替换!
我的结论:您可以使用点,但我不会使用它,因为这可能会导致一些意外行为,具体取决于所使用的 HTTP 服务器。
【讨论】:
你的意思是HTML输入标签的id和name属性吗?
如果是这样,我很想将允许的“输入”名称字符限制(或转换)为仅 az (AZ)、0-9 和有限范围的标点符号(“.”、“”等.),如果只是为了限制 XSS 攻击等的可能性。
另外,为什么要让用户控制输入标签的任何方面? (从验证的角度来看,将输入标签名称保持为“custom_1”、“custom_2”等,然后根据需要映射它们最终可能不会更容易。)
【讨论】: