Currently reading Bloch's Effective Java (2nd Edition) and he makes a point to state, in bold, that overusing POSTs in web applications is inherently bad. Unfortunately, he doesn't specify why.
This startled me, because when I do any web development, all I ever use are POSTs! I have always steered clear of GETs for security reasons and because it felt more professional (long, unsightly URLs always bother me for some reason).
Are there performance differentials between GET and POST? Can anyone elaborate on why overusing POSTs is bad, and why? My understanding - and preliminary searches - seem to all indicate that these two are handles very similarly by the web server. Thanks in advance!
You should use HTTP as it's supposed to be used.
GET should be used for idempotent, read queries (i.e. view an item, search for a product, etc.).
POST should be used for create, delete or update requests (i.e. delete an item, update a profile, etc.)
GET allows refreshing the page, bookmark it, send the URL to someone. POST doesn't allow that. A useful pattern is post/redirect/get (AKA redirect after post).
Note that, except for long search forms, GET URLs should be short. They should usually look like http://www.foo.com/app/product/view?productId=1245, or even http://www.foo.com/app/product/view/1245
You should almost always use GET when requesting content. Only use POST when you are either:
Transmitting sensitive information which should not appear in the URL bar, or
Changing the state on the server (adding/changing/deleting stuff, altough recently some web applications use POST to change, PUT to add and DELETE to delete.)
Here's the difference: If you want to give the link to the page to a friend, or save it somewhere, or even only add it to your bookmarks, you need the full URL of the page. Just like your address bar should say http://stackoverflow.com/questions/7810876/abusing-http-post at the moment. You can Ctrl-C that. You can save that. Enter that link again, you're back at this page.
Now when you use any action other than GET, there is simply no URL to copy. It's like your browser would say you are at http://stackoverflow.com/question. You can't copy that. You can't bookmark that. Besides, if you would try to reload this page, your browser would ask you whether you want to send the data again, which is rather confusing for the non-tech-savy users of your page. And annoying for the entire rest.
However, you should use POST/PUT when transferring data. URL's can only be so long. You can't transmit an entire blog post in an URL. Also, if you reload such a page, You'll almost certainly double-post, because the above described message does not appear.
GET and POST are very different. Choose the right one for the job.
If you are using POST for security reasons, I might drop a mention of other security factors here. You need to ensure that you send the data from a form submit in encrypted form even if you are using POST.
As for the difference between GET and POST, it is as simple as GET is used to send a GET request. So, you would want to get data from a page and act upon it and that is the end of everything.
POST on the other hand, is used to POST data to the application. I am talking about transactions here (complete create, update or delete operations).
If you have a sensitive application that takes, say and ID to delete a user. You would not want to use GET for it because in that case, a witty user may raise mayhem simply changing the ID at the end of the URL and deleting all random uses.
POST allows more data and can be hacked to send streams of files as well. GET has a limited size though.
There is hardly any tradeoff in using GET or POST.
Related
I am little new to programming (especially to web designing). I have learned that the World Wide Web is based upon a protocol called HTTP. And also each and every item (I mean web pages, images, css & js files etc) are transferred according to the HTTP Requests. So my problem is this.
When we fill a web form (especially a login form like fb) and click ok, login or submit button, What Happens Next? Does it send another http request or does it use some special technique?
Is it safe or does anyone can hack our user names and passwords when that requests are traveling through internet?
It actually depends on the person who made it. They can create an output which would show the values entered or it can be entered to a database for other usage. There's so many things can be done and that would actually depend on the need of the user.
Added for 2nd question:
There are a number of ways to encrypt these data to avoid being hacked. If you use a very basic technique in transferring the values that you submit then there would be a huge possibility that it can be hacked. But, not to worry as there are plenty of ways to be safe.
The overall goal is to perform a search on the following webpage http://www.cma-cgm.com/eBusiness/Tracking/Default.aspx with a container value of CMAU1173561. I have tried two approaches, the php extension cURL and python's mechanized. The php approached involves a performing a POST submit using the input fields found on the page (NOTE: These are really ugly on the asp.net page). The returned page does not contain any of the search results. The second approaches involves using python's mechanize module. In this approach I load the page, select the form, then change the text field ctl00$ContentPlaceBody$TextSearch to the container value. When I load the response again no search results.
I am at a really dead end. Any help would be appreciate because as it stands my next step is to become a asp.net expertm which i perfer not to.
The source of that page is pretty scary (giant viewstate, tables all over the place, inline CSS, styles that look like they were copied from Word).
Regardless...an ASP.Net form still passes the same raw data to the server as any other form (though it is abstracted to the developer).
It's very possible that you are missing the cookies which go along with the request. If the search page (or any piece of the site) uses session state, the ASP.Net session cookie must be included in the request. You will be able to tell it from its name (contains "asp.net" and "session").
I assume that you have used a tool like Firebug or Chrome to view the complete outgoing request when the page is submitted. From my quick test, it looks like the request may be performed with a GET, not a POST. I submitted a form, looked at the request, and pasted the URL into a new browser window.
Example: http://www.cma-cgm.com/eBusiness/Tracking/Default.aspx?ContNum=CMAU1173561&T=57201202648
This may be all you need to do.
What is the most standard or best way to persist data between requests?
Should I use cookies or session variables? I'm interested in keeping data like sort order, sort column, and page number (for paginiation).
I'm coming from a webforms background so normally this type of thing was automatically handled for me in the viewstate of the controls I was using.
update
I like the querystring idea, for searching and more meaningful URLs; however, I'm working on an "index/list" view, which consists of a View with header, and "control" options, like DDLs for filtering and a partial view that renders the table of data.
The DDLs use a $.load() to call an ActionResult on the controller, which returns the partial view, passing parameters there in the querystring, but since these are ajax requests the main page url of the user's browser does not get updated.
Is there a best-practice for taking querystrings off the main-page URL and using them in ajax requests to other ActionResults?
If you want it to survive only through one request/redirect TempData is your friend.
However, for things like your pagination, URL is the best method, for the ability to share links alone.
A standard way is to pass those sort of things via URL Query Parameters. You can modify your routing to expect certain URL variables. That way the pages become more search engine friendly as well.
It depends on how permanent you want the information to be:
Things like the page number should indeed be in the URL (as others have pointed out) - this helps with bookmarking, etc, but remember that if you add more content to the list, then that bookmarked result set will not always be what the user wanted...
If you're happy for these values to be lost when a session times out (by default around 20 minutes), then put them in Session.
If you think that sessions are going to timeout before the next request, or you want to save it across visits then you should be storing them in either cookies, or a profile (potentially allowing "Anonymous" profiles, which work with the users cookies, so they would lose them across machines).
Personally, I'd think very carefully about putting sort order and columns in the URL if you do you could actually end up really confusing search engines:
Lots of pages with very similar content (page 1, sorted by date desc, page 1 sorted by date asc, etc) - search engines don't like duplicate content, and nor should you as Google (for instance) will only show two pages from your site in a default result set, you want them to be valid, not duplicates.
Search engines will spend lots more time crawling your site, and potentially give up - If on every page they find links to "Sort by this column", they will attempt to follow them, resulting in more work on the server, higher bandwidth use, etc.
These can be mitigated through the use of a Robots.txt file denying access to sorted versions of the page, but if this is generated almost dynamically that will be very complex to maintain going forward.
In response to your update, a nice way to achieve that for pages would be to have links to "Previous" and "Next" pages of results (or better yet, a list of all pages in the list), output on the page, with the page numbers, that you then hide with JavaScript.
This way users should see your nice, AJAXy behaviour, and search engines (and users without JavaScript - mobile, or those using older screen readers for instance) will still be able to get access to all your pages - this will help your pages to degrade gracefully, or use "Progressive Enhancement".
Things that were previously in viewstate should probably be put back in the clients hands via either hidden fields or cookies.
Session is "too" easy. In a dev environment it works great, pretty much no matter what you put in it. In production scalability and persistence become a problem. In-process session is likely to disappear unexpectedly if you have crashing bug in your site, and requires server affinity when load balancing. Out-of process session fixes the durability and affinity issues, but can still be a performance bottle neck if too much stuff is put in session. A VERY common problem is that each page will put 1 or 2 items into session but never take them out again when they are done. And even if a page removes it session data when it is no longer needed, the data can still get orphaned if a user starts a process and never completes it.
Cookies is a fast and simple way to persist data between requests, and you can also make them live only for a limited time depending on your needs.
Session are easiest.
I'm trying to figure out a logical and quick way to implement the "PRG" design style in a small site I'm doing, and I'm finding an issue I can't think of a good way to solve.
I have a form. It has 2 fields (first and last name). When the user submits the form, I check to make sure that they have data in them before I save it to the database. If they do not, then I show them a nice little error message and leave what little they have entered still in the form.
However, in order to correctly implement PRG, as I understand it, I would have to validate on postback, determine there is an error, then redirect the user to the same page but via get, not post, which would then eliminate any kind of scary message "you are about to resubmit the contents of a form to the server, which can have unintended consequences..." etc if the user reloaded the page.
How can I redirect the user back to the same page and still save their already entered values in the form fields?
I mean, I could pass all the values in the Querystring, but for complex forms this would become very difficult and messy. I could store the values in Session, but that would still be messy, and a good way to bring a webserver to its knees on a busy site.
What do you, my fellow web programmers, do?
As you note, by redirecting, you will lose the data they have entered unless you go through some QueryString gyrations. You are really defeating one of the nice features of asp.net by doing this - the form values are all preserved for you, so that if the page needs to be redisplayed after a post with errors, most of the work is done for you. Why do you want to use a PRG design? What benefit do you expect to get that standard asp.net form handling doesn't give you?
I have written a CMS for a website. You can create pages and do all things you would expect but I am just wanting your opinions on what to do if a user changes the URL of a page. You would need to do a 301 for the previous stored URL but if the user changes the URL 10 times you have to account for all those changes.
Therefore do you not allow users to change the URL or are there other approaches?
Thanks
I'd imagine that a user renaming a page isn't going to happen very often, so you might be able to afford to run a scan through all of the pages in your database looking for references to the previous URI. Present a warning page to the user, saying "All of these pages have links that will now go to 404 because of this change", and give them options:
Establish a 301 as you're thinking
Automagically update the identified links
Don't rename the page
Don't make any of the changes
Of course, you could always just perform the automatic update and let the user back that out too, but that necessitates a fairly complex WAL set up that I can tell you from experience is a huge pain.
Just my $0.02!
If you are worried about the 10 sequential requests caused by the 301's, you could have a script periodically going through all "redirect pages", figure out the most recent URL they now point to, and point them straight there without intermediate redirects.
Alternatively, keep a list of the original URLs along with the lastest one, so you can update all of them when the URL changes again.
Quite a lot of CMS's simply just don't allow the permalinks to be changed so if your worried about not complying with some rule you wouldn't be the first to not allow it.
If you do however implement changing the permalinks (say by changing the title) you'll have to store N titles for each content item and just redirect to the title with the highest id.
ContentItemTitle
id - auto
increment text - unique constraint
contentId - reference
This is linked back to ContentItem as a 1 to 1 relationship.
Then when you recieve a HTTP request for <text> just lookup all the ContentItemTitle rows that share the same <contentId> as <text> and pick the one one with the highest <id> and redirect to that.