tags:

views:

425

answers:

5

I just found out (the hard way), that when you have a HTML form with action="", Webkit browsers treat it differently to Firefox and Internet Explorer.

In FF and IE, these two form tags are equivalent:

<form method="post" action="">

<form method="post">

They will both submit the form back to the same page. Safari and Chrome however will send that first form to the default page (index.php, or whatever) - the second form works the same as FF/IE.

I've quickly hacked my code so that anywhere where it would normally print an empty action, it doesn't add an action attribute at all.

This seems very messy and not the best way to be doing things. Can anyone suggest a better method? Also, can anyone enlighten me about why Webkit would do such a thing?

+6  A: 

The best way in my opinion would be not to omit the action attribute (which would not validate) but to specify the actual action for the form. Is there a reason you are not specifying the action?

Eran Galperin
it's a generic form which is on many pages, some of which could have a series of GET parameters. I've found it much easier to do action="" than to recreate the URL and encode it properly.
nickf
I actually have a helper that parses the url parameters and recreates it accordingly, which I use in most of my projects. Are you using a router pattern? it really helps if your URLs have semantics which are predictable and can be broken down easily.
Eran Galperin
If you tell us a bit more about your environment, there might be a specific answer that makes this easy, for instance, in django, it's usually sufficient to have `action="{{ request.path }}"` to get the same effect.
TokenMacGuy
+6  A: 

I usually use

<form method='POST' action='?'>

This means the current URL but with no parameters.

staticsan
I do this, except I conform to XHTML by using doublequotes. =]
strager
You can use single quotes and still have valid XHTML; you don't have to use double quotes.
Rudd Zwolinski
Oh, my bad. I must be misunderstanding the standards than. Anyway, I prefer doublequotes.
strager
Actually, I thought it was the other way around. No matter.
staticsan
+1  A: 

I've always used (in PHP)

<form method="post" action="<?php echo strip_tags($_SERVER['REQUEST_URI']); ?>">

To get my forms to submit to themselves. This however, isn't enough to cover XSS attacks. I've now dedicated a question to this aspect above.

alex
As I already said: Use `htmlspecialchars()` and not `striptags()`!
Gumbo
+2  A: 

This has/was apparently filed as a bug against webkit here

Scott Evernden
A: 

The action attribute is required but you can specify an empty URI reference that referes to the current URI:

<form method="POST" action="">

Edit    Ok, this actually is a filed bug of WebKit 528+ (see Bug 19884) when an empty URI is used with a specified base URI using the BASE element. In that case WebKit takes the base URI instead of resolving the empty URI from the base URI.

But this is correct behavior according to RFC 3986:

5.1. Establishing a Base URI

The term "relative" implies that a "base URI" exists against which the relative reference is applied. […]

The base URI of a reference can be established in one of four ways, discussed below in order of precedence. The order of precedence can be thought of in terms of layers, where the innermost defined base URI has the highest precedence. This can be visualized graphically as follows:

  .----------------------------------------------------------.
  |  .----------------------------------------------------.  |
  |  |  .----------------------------------------------.  |  |
  |  |  |  .----------------------------------------.  |  |  |
  |  |  |  |  .----------------------------------.  |  |  |  |
  |  |  |  |  |       <relative-reference>       |  |  |  |  |
  |  |  |  |  `----------------------------------'  |  |  |  |
  |  |  |  | (5.1.1) Base URI embedded in content   |  |  |  |
  |  |  |  `----------------------------------------'  |  |  |
  |  |  | (5.1.2) Base URI of the encapsulating entity |  |  |
  |  |  |         (message, representation, or none)   |  |  |
  |  |  `----------------------------------------------'  |  |
  |  | (5.1.3) URI used to retrieve the entity            |  |
  |  `----------------------------------------------------'  |
  | (5.1.4) Default Base URI (application-dependent)         |
  `----------------------------------------------------------'

In this case the BASE element with href attribute is a base URI embedded in content. And base URI embedded in content has a higher precedence than URI used to retrieve the entity. So WebKit’s behavior is actually the expected behavior according to RFC 3986.

But in HTML 5 this behavior of an empty URI in form’s action (still a draft) differs from RFC 3986:

If action is the empty string, let action be the document's address.

Note: This step is a willful violation of RFC 3986, which would require base URL processing here. This violation is motivated by a desire for compatibility with legacy content. [RFC3986]

Frankly, an HTML comment after this note in the source code reads:

<!-- Don't ask me why. But that's what IE does. It even treats
action="" differently from action=" " or action="#" (the latter
two resolve to the base URL, the first one resolves to the doc
URL). And other browsers concur. It is even required, see e.g.
  http://bugs.webkit.org/show_bug.cgi?id=7763
  https://bugzilla.mozilla.org/show_bug.cgi?id=297761
-->

So this is rather a bug originated from Internet Explorer that became a de-facto standard.

Gumbo
...except that doesn't work in Webkit browsers, as mentioned in the OP.
nickf
The second example is not valid HTML either.
Gumbo
well no, but it actually works, which is slightly more important.
nickf