在HTML表单的action属性中使用空URL是一个好习惯吗?(action="")

314

7
建议将“最佳实践”标签应用于此内容。 - Will Morgan
为了双重确认,请将操作留空,或者根本不提及任何操作(例如 <form name="xyz" >)。它会自动提交操作。 - Jackie
12
不包括action属性会使页面容易受到 iframe clickjacking 攻击,例如攻击者将您的页面包裹在一个iframe中,并且iframe URL 包括与表单字段相同名称的查询参数。当提交表单时,查询值会插入数据库,因此用户的身份信息(电子邮件、地址等)已经被泄露。 - Paul Sweatte
那么,提交表单到当前页面的有效、安全方式是什么? - Costa Michailidis
不包括action属性也是无效的HTML。它在规范中作为必需属性。空操作也有其自己的怪癖:https://dev59.com/T3RC5IYBdhLWcg3wFNDX#617197。 - Suncat2000
10个回答

305

最好的做法是完全省略 action 属性。如果将其省略,则表单将被提交到文档的地址,即同一页面。

也可以将其留空,并且任何实现 HTML 表单提交算法 的浏览器都会将其视为等同于文档的地址,这主要是因为当前浏览器的工作方式:

8. 将 action 设为提交元素的 action

9. 如果 action 是空字符串,则将其设为 文档的地址

注意:此步骤是对 RFC 3986 的 故意违规,该规范要求在此处进行基本 URL 处理。这种违规是出于与遗留内容兼容性的考虑。[RFC3986]

这在所有现代浏览器中肯定可行,但在一些旧版浏览器中可能无法按预期工作("浏览器对空 action="" 属性的处理有些怪异"),这就是为什么规范强烈建议作者不要留空:

actionformaction内容属性如果指定,则必须具有有效的非空URL,可能被空格包围


18
可能自您的回答以来(已经过去将近三年),情况可能已经有所改变,但截至今天,HTML5不允许使用action = ""——请参见我的答案... - derobert
2
@derobert 谢谢。这可能没有改变。我已经修改了我的答案,以更好地反映规范所说的内容。 - mercator

85

实际上,当前HTML5草案的表单提交子部分不允许action=""。这违反了规范。

actionformaction内容属性(如果指定),必须具有有效的非空URL值,可能带有空格。(强调添加)

mercator's answer中引用的部分是对实现的要求,而不是作者的要求。作者必须遵循作者要求。引用How to read this specification

特别地,有适用于生产者(例如作者和他们创建的文档)的一致性要求,以及适用于消费者(例如Web浏览器)的一致性要求。它们可以通过它们所要求的来区分:对生产者的要求说明了允许什么,而对消费者的要求则说明了软件应如何行动。

HTML4允许空URL,但由于“浏览器对空的action=""属性会产生奇怪的行为”,因此进行了更改。考虑到更改的原因,在HTML4中最好也不要这样做。

1
它是否允许完全不使用“action”属性来指示表单应提交到文档地址?似乎是这样的,因为它说:“如果指定”。 - Kerrick
3
是的,我相信HTML5允许完全省略action属性,并将其默认为一个空字符串。而HTML4则不行,它规定了action属性为必需项。 - derobert
我同意@Kerrick的观点,可以省略action属性。根据当前HTML5草案的阅读,似乎不允许使用空字符串,但是允许省略该属性。但无论如何,出于兼容性考虑,我建议您始终包括“action”属性,并将其填充为有效的非空URL(良好的实践始终是最好的方式)。 - serfer2
一个潜在的问题:AngularJS将阻止没有操作属性的表单提交。这可能不是一个常见的问题,但我花了一段时间才弄清楚我们遗留网站的某些部分为什么开始出现故障。 - Asmor
这个答案让我感到困惑,当我6个月前第一次阅读它时,我认为它是在说被接受的答案是错误的。我认为最好的方式是将属性省略掉,但如果属性存在,则给它一个非空值可能会更好理解。 - run_the_race

21

不包括 action 属性会导致页面容易受到 iframe 点击劫持 攻击,攻击包括以下几个简单步骤:

  • 攻击者将您的页面包装在 iframe 中
  • iframe URL 包含与表单字段相同名称的查询参数
  • 提交表单时,查询值被插入到数据库中
  • 用户的身份信息(电子邮件、地址等)已被泄露

参考资料


2
iframe的URL不是包含GET参数吗?而表单通常使用POST提交,所以如果网站只处理POST参数,那就不应该有问题了,对吧?至少我在PHP中处理表单时通常只使用$_POST数组。 - Calmarius
2
@Calmarius 是的,使用 $_POST 而不是 $_REQUEST 可以避免这种情况。如果框架代码使用了 $_REQUEST,可以使用一个 iframe buster - Paul Sweatte

18

这将使用HTML5进行验证。

<form action="#">

4
我没有尝试过,但从概念上讲,在提交后不是应该滚动到页面顶部吗? - Matt Mitchell
2
你能不能使用 action="." - s427
4
action="?" 也可以正常工作。它会验证并指向当前页面,不包含查询字符串数据。 - Chris Broski
5
对于一般情况来说,action="." 是一个不好的选择。像 example.com/login 这样的URL仅被映射为 example.com/ - Torsten Bronger
1
只有当用户想要滚动到页面顶部时,此答案才有效。 - GeorgeButter
显示剩余2条评论

13

在 HTML 5 中,action="" 不被支持,因此不要这样做。这是一种不好的做法。

相反,如果完全取消 action,它会默认提交到同一页。我认为这是最佳实践:

<form>This will submit to the current page</form>

如果您正在使用PHP提交表单,您可能需要考虑以下内容。 在此处阅读更多信息。

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

或者您可以使用#,但请记住这将像锚点一样,滚动到页面顶部。

<form action="#">

你没有设置动作属性,这个表单仍然容易受到攻击吗?在链接的第一页有详细说明。 - Richard Young
1
@RichardYoung 抱歉,我不理解你的问题。请重新表述。 - GeorgeButter
1
$_SERVER["PHP_SELF"]变量可能被黑客利用。如果您的页面中使用了PHP_SELF,则用户可以输入斜杠(/),然后执行一些跨站脚本攻击(XSS)命令。 如果省略action属性,您是否仍然容易受到此类攻击? - Richard Young
是的,你是。可以在客户端添加动作属性并赋予任何选择的值。但是使用htmlspecialchars()函数可以防止他人利用你的php脚本攻击你。 - GeorgeButter
我知道htmlspecialchars()函数,但我希望如果我省略了该操作,就可以绕过它。谢谢你为我澄清这一点。 - Richard Young
省略“_required_”动作属性违反了HTML规范。 - Suncat2000

4

我认为最好明确地说明表单提交的位置。如果您想要完全安全,请在操作属性中输入与表单相同的URL,以便将其提交回自身。尽管主流浏览器将""评估为同一页面,但无法保证非主流浏览器会这样做。

当然,整个URL包括GET数据,就像Juddling指出的那样。


2

只需使用

<form action="?" method="post" enctype="multipart/form-data" name="myForm" id="myForm">

它不违反HTML5标准。


我没有点踩,但你的方法会丢失所有"get"参数。在下面的网址上的表单将会破坏“example.com/update_user?user_id=1”,因为该表单将提交到“example.com/update_user?”。 - vikki

1

我过去通常不指定 action 属性。实际上,我的框架是这样设计的,所有页面都会被提交到同一个地址。但今天我发现了一个问题。有时我借用 action 属性值来进行后台调用(我猜有些人称之为 AJAX)。所以我发现,如果没有指定 action 属性,IE 会将其保留为空。在我看来有点奇怪,因为如果没有指定 action 属性,JavaScript 对应属性至少应该是未定义的。无论如何,我的观点是,在选择最佳实践之前,您需要更多地了解上下文,比如是否在 JavaScript 中使用该属性。


1

我曾经在使用Classic ASP时经常这样做。通常,当需要对输入进行服务器端验证(在AJAX出现之前)时,我会使用它。我看到的主要缺点是,在文件级别上它不能将编程逻辑与演示分开。


1
为什么不呢?我认为它没有连接。我可以让表单将数据提交到同一页,并使用适当的控制器和视图分离来构建此页面。 - markus

0

当您将空操作放置时,某些安全过滤器会认为它是恶意或钓鱼行为。因此,它们可能会阻止您的页面。因此建议不要保留action = blank。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接