[Php] Why the hash part of the URL is not in the server side?


Answers

http://tools.ietf.org/html/rfc2396#section-4

When a URI reference is used to perform a retrieval action on the identified resource, the optional fragment identifier, separated from the URI by a crosshatch ("#") character, consists of additional reference information to be interpreted by the user agent after the retrieval action has been successfully completed. As such, it is not part of a URI, but is often used in conjunction with a URI.

Question

For example if I type in the URL:

http://www.foo.com/page.php?parameter=kickme#MOREURL

In the server isn't the part: #MOREURL

Is possible to send or get these part to the server without jQuery AJAX?.

Thanks




As the browser does not send the hash to the server by default, the only way to do it is to use some Javascript:

  1. When the form submits, grab the hash (window.location.hash) and store it in a server-side hidden input field Put this in a DIV with an id of "urlhash" so we can find it easily later.

  2. On the server you can use this value if you need to do something with it. You can even change it if you need to.

  3. On page load on the client, check the value of this this hidden field. You will want to find it by the DIV it is contained in as the auto-generated ID won't be known. Yes, you could do some trickery here with .ClientID but we found it simpler to just use the wrapper DIV as it allows all this Javascript to live in an external file and be used in a generic fashion.

  4. If the hidden input field has a valid value, set that as the URL hash (window.locaion.hash again) and/or perform other actions.

We used jQuery to simplify the selecting of the field, etc... all in all it ends up being a few jQuery calls, one to save the value, and another to restore it.

Before submit:

$("form").submit(function() {
  $("input", "#urlhash").val(window.location.hash);
});

On page load:

var hashVal = $("input", "#urlhash").val();
if (IsHashValid(hashVal)) {
  window.location.hash = hashVal;
}

IsHashValid() can check for "undefined" or other things you don't want to handle.

Also, make sure you use $(document).ready() appropriately, of course.




Why the hash part of the URL is not in the server side?

No, it is available to the browser only, so you have to deal it with Javascript. The server can not read it.

Explanation:
Basically the hash component of the page URL (the part following the # sign) is processed by the browser only - the browser never passes it to the server. This sadly is part of the HTML standard and is the same whether or not you are using IE or any other browser (and for that matter PHP or any other server side technology).

Here's what Wikipedia says about it:

The fragment identifier functions differently than the rest of the URI: namely, its processing is exclusively client-side with no participation from the server. When an agent (such as a Web browser) requests a resource from a Web server, the agent sends the URI to the server, but does not send the fragment. Instead, the agent waits for the server to send the resource, and then the agent processes the resource according to the fragment value. In the most common case, the agent scrolls a Web page down to the anchor element which has an attribute string equal to the fragment value. Other client behaviors are possible




How can I extract URL parameters with hash?

simplified - not beauty... just for showing a possibility and pointing you in the right direction. Returns http://i.imgur.com/e0XJI.jpg

<?php
$url = 'http://www.example.com/edit-your-profile/#file%5B0%5D%5Bstatus%5D=Complete&file%5B0%5D%5BremoteFileURL%5D=http%3A%2F%2Fi.imgur.com%2Fe0XJI.jpg&file%5B0%5D%5BfileSource%5D=Previous%20Uploads&file%5B0%5D%5BpicID%5D=p43';
$urlDecoded = urldecode($url);
$urlParts = parse_url($urlDecoded);

$matches = array();
$regexRemoteUrl = preg_match('/remoteFileUrl\]=([^&]+)/i', $urlParts['fragment'], $matches);
// remoteFileURL
echo($matches[1]);
?>



If you wanted it in Javascript, here's a simply bit of regex that will get it for you:

decodeURI(window.location.hash).match(/remoteFileURL]=([^&]+)/)[1]

It returns "http%3A%2F%2Fi.imgur.com%2Fe0XJI.jpg" for me

so we use unescape:

unescape(decodeURI(window.location.hash).match(/remoteFileURL]=([^&]+)/)[1])

to get "http://i.imgur.com/e0XJI.jpg"