Can I read the hash portion of the URL on my server-side application (PHP, Ruby, Python, etc.)?
Asked Answered
P

13

231

Assuming a URL of:

www.example.com/?val=1#part2

PHP can read the request variables val1 using the GET array.

Is the hash value part2 also readable? Or is this only upto the browser and JavaScript?

Periodicity answered 2/6, 2009 at 17:41 Comment(0)
W
215

The main problem is that the browser won't even send a request with a fragment part. The fragment part is resolved right there in the browser. So it's reachable through JavaScript.

Anyway, you could parse a URL into bits, including the fragment part, using parse_url(), but it's obviously not your case.

Whorish answered 2/6, 2009 at 17:45 Comment(0)
H
100

Simple test, accessing http://localhost:8000/hello?foo=bar#this-is-not-sent-to-server

python -c "import SimpleHTTPServer;SimpleHTTPServer.test()"
Serving HTTP on 0.0.0.0 port 8000 ...
localhost - - [02/Jun/2009 12:48:47] code 404, message File not found
localhost - - [02/Jun/2009 12:48:47] "GET /hello?foo=bar HTTP/1.1" 404 -

The server receives the request without the #appendage - anything after the hash tag is simply an anchor lookup on the client.

You can find the anchor name used within the URL via javascript using, as an example:

<script>alert(window.location.hash);</script>

The parse_url() function in PHP can work if you already have the needed URL string including the fragment (http://codepad.org/BDqjtXix):

<?
echo parse_url("http://foo?bar#fizzbuzz",PHP_URL_FRAGMENT);
?>

Output: fizzbuzz

But I don't think PHP receives the fragment information because it's client-only.

Hautboy answered 2/6, 2009 at 17:57 Comment(0)
L
48

It is retrievable from Javascript - as window.location.hash. From there you could send it to the server with Ajax for example, or encode it and put it into URLs which can then be passed through to the server-side.

Leucas answered 2/6, 2009 at 17:53 Comment(1)
Thanks! So to be clear, instead of this: www.example.com/?val=1#part2 You'd have to redirect to it on the server, like this: www.example.com/?redirectUrl=%2F%3Fval%3D1%23part2 and of course you'd have to add in support to redirect to that other url in your other page. Not awesome, and doesnt work for all use cases of course, but does work for bookmarks. Note that if you do this, you shouldnt allow redirects to absolute urls, only relative urls, to ensure you don't open yourself up to unsafe redirectsSpiritual
S
26

The hash is never sent to the server, so no.

Spacing answered 2/6, 2009 at 17:44 Comment(0)
E
9

The answer is no.

The main purpose of the hash is to scroll to a certain part of the page where you have defined a bookmark. e.g. Scroll to this Part when page loads.

The browse will scroll such that this line is the first visible content in the page, depending on how much content follows below the line.

Yes javascript can acces it, and then a simple ajax call will do the magic

Esmaria answered 29/6, 2011 at 13:6 Comment(0)
G
5

What about:

Dynamically grab the #hash

<script>
var urlhash = window.location.hash, //get the hash from url
    txthash = urlhash.replace("#", ""); //remove the #
    //alert(txthash);
</script>

<?php
$hash = "<script>document.writeln(txthash);</script>";
echo $hash;
?>

To make it more fluent:

Full Example using just Javascript and PHP

<script>
var urlhash = window.location.hash,  //get the hash from url
txthash = urlhash.replace("#", "");  //remove the #

function changehash(a,b){
   window.location.hash = b; //add hash to url
   //alert(b); //alert to test
   location.reload(); //reload page to show the current hash
}
</script>

<?php $hash = "<script>document.writeln(txthash);</script>";?>

<a onclick="changehash(this,'#hash1')" style="text-decoration: underline;cursor: pointer;" >Change to #hash1</a><br/>
<a onclick="changehash(this,'#hash2')" style="text-decoration: underline;cursor: pointer;">Change to #hash2</a><br/> 

<?php echo "This is the current hash: " . $hash; ?> 
Glop answered 6/8, 2019 at 2:16 Comment(2)
PHP still doesn't get the hash value.Pampa
sweet and short solution.Dissimulation
K
3

I think the hash-value is only used client-side, so you can't get it with php.

you could redirect it with javascript to php though.

Keyway answered 2/6, 2009 at 17:47 Comment(0)
H
2

Th part of an URI after the # is called "fragment" and is by definition only available/processed on client side (see https://en.wikipedia.org/wiki/Fragment_identifier).

On the client side, this can be accessed using javaScript with window.location.hash.

Heinous answered 27/12, 2016 at 18:15 Comment(0)
T
0
<?php
$url=parse_url("http://domain.com/site/gallery/1?user=12#photo45 ");
echo $url["fragment"]; //This variable contains the fragment
?>

This is should work

Tourism answered 17/7, 2014 at 5:11 Comment(2)
IF you have the url as string is easy, even if you parse it with reg exp. The problem is that you can't access #photo45 from the server (use phpinfo() and you won't see #photo45 anywhereSabayon
That does not do anything on the initial request for that pageIstria
H
0

Yes you can:

Use this method to prevent errors:

<script> 
query=location.hash;
document.cookie= 'anchor'+query;
</script>

And of course in PHP, explode that puppy and get one of the values

$split = explode('/', $_COOKIE['anchor']);
print_r($split[1]); //to test it, use print_r. this line will print the value after the anchortag
Humidifier answered 7/3, 2017 at 3:21 Comment(1)
That does not do anything on the initial request for that pageIstria
T
0

We can do it with another approach too, Like first of all get the hash value from js and call the ajax using that parameter and can do whatever we want

Tourism answered 15/5, 2018 at 4:7 Comment(0)
S
0

Here is more complete code that you can start with:


<script>
    sendTokenParameter();

    function sendTokenParameter() {
        if (!window.location.hash) {
            return;
        }

        const id_token = window.location.hash.split('&').filter(function(el) { if(el.match('id_token') !== null) return true; })[0].split('=')[1];
        if (!id_token) {
            console.error('No token returned');
            return;
        }

        window.location.href = `${window.location.pathname}?id_token=${id_token}`
    }
</script>

<?php

process_login();
function process_login() {
    $id_token = $_GET['id_token'];
    if (!$id_token) {
        // Let the javascript code to send the token
        return;
    }
    
    // Do stuff with the token
    
}

?>

Stackhouse answered 25/11, 2023 at 19:27 Comment(0)
D
-1

Another solution is to add a hidden input field to the php page:

<input type="hidden" id="myHiddenLocationHash" name="myHiddenLocationHash" value="">

Using javascript/jQuery you can set the value of this field on the page load or responding to an event :

$('#myHiddenLocationHash').val(document.location.hash.replace('#',''));

In php on the server side you can read this value using the $_POST collection:

$server_location_hash = $_POST['myHiddenLocationHash'];
Disaffiliate answered 30/3, 2017 at 13:24 Comment(2)
That does not do anything on the initial request for that pageIstria
I agree, it works for the subsequent requests, not for the first load.Disaffiliate

© 2022 - 2024 — McMap. All rights reserved.