6

I wonder if this is a mistake, but right now I'm using GET for all my search URLs. The reason is that with GET Url the users can simple copy the link on the address bar and share or save easily. It seems like Google for example also uses GET Url (form).

Since it's a search form with filters, sorters and such the length of the generated URL can be unpredictable. I'm worried about the edge cases where the URL may exceed the length limit. On possible solution is to actually POST the data, then generate a unique hash based on that data, then use that has as the URL for the search. This solution does require saving the actual form data to database for example, then re-querying it on every search request which seems to be wasteful.

I wonder if there is any other way I haven't thought of yet?

Edit: I would like to say thank to all your answers here, they helped alot. I will summarize below what I did to solve this, hope it helps someone else:

  1. As pointed out, if the URL gets too long (over 2000 chars) then perhaps I'm doing something wrong. So I went back and revisited my algorithm and managed to cut the info I have to pass via the GET string more than half of what I had (previously, it can easily get over 500 chars which got me worried)
  2. I also jsonified my string. The reason is that deep nested array does not work well on query string, and by jsonifying the array I actually got a rather shorter and easier to read result
  3. There is another solution, that is to write up your own parser, for example if you want to get even shorter url you could write: category=1,2,3,4,5 and since you already know your query structure you can do the parsing in your backend. It takes a bit more work so I haven't tried that yet till I really have to
  4. I haven't tried the hashing/token route yet, but I believe it's also a good solution if you really really have to handle huge input. You can POST the input, then issue back a hash string token to use as the search URL.
mr1031011
  • 3,574
  • 5
  • 42
  • 59
  • 3
    There is no "maximum" length set in the HTTP protocol, but browsers have some limitations. However these are really big numbers, I wouldn't worry about it. More information about url lengths can be found here: http://www.boutell.com/newfaq/misc/urllength.html – Kevin Dec 14 '14 at 02:52
  • If you don't need a database for GET you will not need one for POST. Why not store this data in a session? – Spencer Wieczorek Dec 14 '14 at 02:55
  • @Jonast92 thank you I didnt find that when I searched, I will see if there is any good solution in there then will close this question – mr1031011 Dec 14 '14 at 04:46
  • @SpencerWieczorek saving the url in session means that the user cannot share the url which is not desirable in my specific case. – mr1031011 Dec 14 '14 at 04:47
  • @Jonast92 the 'duplicate' is tediously verbose and has as its accepted answer the approach of using a POST request instead of a GET, which the asker here has given good reasons for wanting to avoid. I'm voting to keep open. – Mark Amery Dec 15 '14 at 00:29

1 Answers1

9

First of all, according to this Stack Overflow answer, you're fine up until 2000 characters1.

Once you hit that limit, if you want to keep your URLs shareable, you have a couple of choices I can see:

  1. As you proposed, use POST requests to store the actual query and associate it with a hash, and then subsequent GET requests to run the query and retrieve the results.
  2. Compress your query string clientside and decompress it serverside.

Let's consider the relative merits of these approaches.

In favour of hashing...

  • You can keep the URLs arbitrarily small (and of a fixed length, say 12 or 16 characters), whereas if you go the compression route you're likely to end up with longer (and hence uglier) URLs.
  • Your searches can become arbitrarily long - they can be enormous thousand-page documents if for some perverse reason you need them to be. (You probably don't.)
  • You can trivially do this out of the box in PHP with hash, whereas it's less obvious what tools to use for the compression approach.

In favour of compression...

  • Performance. The hashing approach requires two requests to the server whenever the user does a search, which is inevitably going to have a user-visible performance impact since you're paying the latency cost of an extra round-trip to the server each search. (Okay, if you hash clientside and speculatively try a GET with the calculated hash before you know whether it's stored, then you could reduce this to 1 request for searches that somebody has performed before, but you'd do so at the price of making new searches take 3 requests.)
  • You don't need to store a mapping of hashes to queries anywhere. Depending upon your circumstances, putting these in the database may be a performance trap - or a disk usage problem - years down the line when the table has hundreds of millions of rows.

Some of these factors may be irrelevant to you, depending upon your circumstances; I leave it to you to weigh up your priorities.

If you want to go the compression route, I don't know what tool to recommend to you. How to compress URL parameters may be a good place to start looking. Perhaps also consider https://github.com/pieroxy/lz-string to compress with https://github.com/nullpunkt/lz-string-php to decompress.


1 Note that a 2000 character URL is quite long. Are your URLs really this long?

https://www.google.com/search?as_q=you+have+to+write+a+really+really+long+search+to+get+to+2000+characters.+like+seriously%2C+you+have+no+idea+how+long+it+has+to+be&as_epq=2000+characters+is+absolutely+freaking+enormous.+You+can+fit+sooooooooooooooooooooooooooooooooo+much+data+into+2000+characters.+My+hands+are+getting+tired+typing+this+many+characters.+I+didn%27t+even+realise+how+long+it+was+going+to+take+to+type+them+all.&as_oq=Argh!+So+many+characters.+I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.+I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.I%27m+bored+now%2C+so+I%27ll+just+copy+and+paste.&as_eq=It+has+to+be+freaking+enormously+freaking+enormous&as_nlo=123&as_nhi=456&lr=lang_hu&cr=countryAD&as_qdr=m&as_sitesearch=stackoverflow.com&as_occt=title&safe=active&tbs=rl%3A1%2Crls%3A0&as_filetype=xls&as_rights=(cc_publicdomain%7Ccc_attribute%7Ccc_sharealike%7Ccc_nonderived).-(cc_noncommercial)&gws_rd=ssl

Community
  • 1
  • 1
Mark Amery
  • 143,130
  • 81
  • 406
  • 459
  • 1
    I've gotten to the point where my search has to be represented in URL so the user can basically copy-paste the same code over to other people. The thing is we have categories (pretty much like the ones on Ebay) but we allowed users to select them with checkboxes so you can make a link consisting of +4k characters. How would you approach it when there's (I thin) no way to flatten the search. – Łukasz Formela Jul 10 '20 at 12:25
  • I have the same problem and decided to use multipart POST request. – Pavel Madr Nov 13 '20 at 07:17