Posting a form to itself without trickery, using an empty ACTION attribute
In the first iteration of this entry, I referred to the two approaches of either providing an empty ACTION or none at all, but as the comments below show, the former violates the HTML spec. So let's stick with the notion of an empty ACTION. Same result, though.
How often have we all seen code along the lines of:
...
or more involved:
<cfif CGI.QUERY_STRING NEQ "">
<cfset action=action & "?" & xmlformat(CGI.QUERY_STRING)>
</cfif>
<form action="<cfoutput>#action#</cfoutput>" method="post">
...
All this could be replaced very simply with:
...
The form will post back to itself. I'll offer another post that shows a unique way to take advantage of this. In any case, I hope that this observation may help some folks.
Is this reliable?
Now, there are some who will argue that this is a violation of the
Again, a clarification over what I wrote originallyhere. As was refined in the comments below, it's a violation to have *no* ACTION, but it's perfectly legit according to the URI spec (section 4.2 at http://www.ietf.org/rfc/rfc2396.txt) to have an empty ACTION, which is interpreted as a "same-document reference. (Thanks, Christopher Bradford, for that info.) Given that, even the following cautions seem needless, but I'll leave them for any still concerned.
If you have any hesitation, because you have to support multiple browsers and you can't test all possibilities, I'll understand if you choose to pass on this. But certainly if you only need to support browsers you can test, then if it works as expected, enjoy.
If anyone reading this can offer where this is the case, I'd appreciate hearing it. If you want some simple code to test, try this:
<input type="Submit">
</form>
<cfif cgi.request_method is "post">
Posted to itself
</cfif>
If it shows the text within the IF, then it worked as expected.
What about query string info?
You may wonder about the earlier more involved examples that showed passing the query string, in case any had been passed to the form. No problem. This technique passes any query string along just fine. Try it yourself (add ?test=test to the form and view in the debugging info that it's still in the URL scope after submission.)
Again, I'll offer another post that shows a unique way to take advantage of this in doing login authentication.






Knowing it is a violation of the HTTP spec alone is enough for me to not use this technique. While it may work on every browser today, it may not work on IE 8 or FF 3 if they decide to be more standards compliant. I really do not want to fix countless forms in the future.
The next developer that comes along may not have read this blog post, and wastes his time trying to figure out where the form posts to. ( "I just searched through 3 embedded js files and still don't see where the form posts to!")
Adding cgi.script_name?cgi.query_string is trivial.
And even if someone found it, I'd think it would still have to be evaluated against similar "against the spec" features that we may all use. I mean, we can be purist about it, but if someone could show that there are other similar "anti-spec" things that are widely used (and that we might ourselves use) then I would think that mitigates the concern for purity. But to each his own, of course.
I suppose one may argue that they did this in response to the very concern that Gus has raised. If anyone at Adobe happens to be reading this and can report why it was changed that could help the argument (though the simple fact that CFFORM now does it isn't enough motivation in and of itself for me to argue against the no-action approach). Again, just my opinion.
According to the HTML 4 spec Section 17.3 the Acction is a required attribute of the form element:
http://www.w3.org/TR...
Having said that, I think there are myriad reasons to ignore the specs, I just think eliminating a form action is not a very good reason to do so as it is so easy to comply with the spec. Most of the time when the spec is ignored it is due to poor or non-compliance to the spec by browsers, thus workarounds are used. This is different than the case being discussed.
There are exceptions to every rule, but as a rule I would continue to recommend providing an action to html forms.
4.2. Same-document References
A URI reference that does not contain a URI is a reference to the
current document. In other words, an empty URI reference within a
document is interpreted as a reference to the start of that document,
and a reference containing only a fragment identifier is a reference
to the identified fragment of that document. Traversal of such a
reference should not result in an additional retrieval action.
However, if the URI reference occurs in a context that is always
intended to result in a new request, as in the case of HTML's FORM
element, then an empty URI reference represents the base URI of the
current document and should be replaced by that URI when transformed
into a request.
It seems that this is reliable, consistent, and standards-compliant behavior.
<form action="<cfoutput>#cgi.script_name#?#cgi.query_string#</cfoutput>" method="post">
You must check cgi.query_string doesn't contain <script> tags or whatever else XSS you can think of...
I use replace(cgi.query_string,"<","","ALL") in the blogCFC on my site..
Christopher, thanks for your clarification that I misspoke in saying some had called it a violation of the HTTP spec. As Gus showed, the HTML spec says it should be there.
But you make a great point that if CAN be there and be empty. In case anyone would ask, what's the URL for that? I tried to find it but could not readily.
So it seems that while one could argue that you should not leave it off, you can leave it with an empty value (which I said, but did not show, in the blog entry). That's a fine clarification.
Finally, Geoff, you, too, make a great point. In fact, I was going to offer code that did address that, doing an xmlformat(cgi.query_string) but decided to leave it out as I was arguing that the querystring appending was unneeded. But yes, if one does leave it, then it's wise to consider security concerns.
(Indeed, this argues yet another reason to just leave it blank and leave it to the browser to pass along whatever is sent. As for whether the ultimate action page should further validate the input URL variables for potentially bad data, that's an entirely different subject that I'd rather not open for discussion in this comments of this blog entry.)
http://www.ietf.org/...
My pages validate too.
It does the same thing, but you are using the required attribute.
Recently in a rushed coding frenzy I did:
action="?mcp=1234-4567-7890&id=whatever" method="post"
instead of putting them as hidden form fields.
It does work in most browsers, the form submits to itself, and you can read the url vars and form vars. It does NOT work in safari, and probably should NEVER be done anyways. Just something I learned, and do not do in production!
If it's just the failure in Safari, might that rather be an error in Safari?
And I guess I'd also ask if it's specific to the self-referencing form of ACTION being discussed here. I mean, even if you provided a filename, are you saying that you should not use a query string on an action?
I'm not saying you should. Just looking for clarification, for future readers, especially if someone can point to a definitive document on the topic.
Using a filename would have been a standard relative path.
I didn't get a chance to check all browsers, I develop in FF, check in IE. A few people I work with have Macs, and noticed this problem.
"Do not do it in production" - simply because you can make it work in all browsers without breaking standards by adding the filename. Not to say query string only is not standard (I don't know either way) (might be only a safari bug?) But if you know it breaks a browser, and you can make it work while upholding standards, that's probably the way to think about doing it.
To clarify, as soon as I specified filename or used a absolute path, it worked fine in safari too.
action="?id=3&this=that" broke in safari with the action url being formated like
domain.com/filename.cfm?id=3&this=that?id=3&this=that
Now you raise a good point. If the use of just a querystring fails on Safari, then it's certainly worth thinking twice before using it. It's still unclear if doing so is against the standard. Just because it fails on Safari doesn't make it "non standard" (nor is it clear that doing it makes your code "uphold standards".
I'm being a bit pedantic. I do appreciate your pointing out the challenge and solution, and thank you for bringing it up. Each can decide for themselves how to respond to all this.
I am in agreement with your post! I just thought I would point out that a querystring only may cause problems in safari, and to avoid that problem is simple, and doesn't break standards (not a hack just for safari.)
All Good!
I'm currently working on a form where I've tried to get away with the empty action attribute. I tested it on my cell phone, but it refuses to submit the form; instead, it throws an "Invalid web address" error.
I recommend a full-blown URI for the action attribute.
(My cell phone UA string: Nokia6030b/2.0 (m3.35) Profile/MIDP-2.0 Configuration/CLDC-1.1 UP.Link/6.3.0.0.0)
On Apache/1.3.37 this results in a 405 error
The requested method POST is not allowed
And if me, then what part of my original post are you referring to? My original suggestion that you need not include any Action? Or my update about leaving it empty?
To answer your questions, yes of course I "actually tested it", but no, I'll admit not against multiple web servers (sorry, just didn't think of that), but yes of course I was using HTML. What else might you think I was using? Seems an odd (almost surly) question.
Also, as the commenter previous to you had said, this could also be affected by browsers, so I'll ask you, what browser were you using? If we're going to get to the bottom of any aspect of this which doesn't apply to all, let's do it across the board.
I have to say I don't care much for your tone. Do you know me? (Or even if you're responding to a commenter, do you know that person?) You just sound awfully accusatory, like you're trying to prove a point, or assert that I've wasted your time (or that of others). Chill out. I was sharing a tip, and one that's helped me out (and others) quite a bit over the years. If it's not a perfect tip, that's indeed what the comments are for. But I'm here trying to help people. I'd like to ask you to do the same.
@Experienced, can you not interpret what it is saying? It is in plain English - it says that the POST method is not allowed - that doesn't mean that it happened because of you leaving your action attribute empty - Apache/1.3.37 obviously is not set up to allow post requests to your specific page, or that it is set up to reject post requests to that specific page, this has nothing to do with the action attribute! To work around the problem, you should google to try and find out how you can allow post requests to your specific page, or maybe use GET, or whatever