Nginx discards data after number sign (#)

nginxPROXYrewrite

I have existing request which looks like
https://smth.ru/smth/GET_DATA?p_DATA_TYPE=arg1#arg2&arg2=XXX

I know that is awfully incorrect but I have to work with it. And it worked ealier with apache.

Now I need nginx to work as proxy for this request. But it simply discards everything after "#" and I can't find it in any variables like $query_string

That's why backend server receives only
https://smth.ru/smth/GET_DATA?p_DATA_TYPE=type

How can I get parameters after # or make nginx proxy full request?

My server block looks like

server
{
...
location /
{

    proxy_pass_header       Authorization;
    proxy_pass_request_headers on;
    proxy_pass http://127.0.0.1:8080/$request_uri?$query_string;
    proxy_set_header Host            $host;
    proxy_set_header X-Forwarded-For $remote_addr;

}
...
}

Passing proxy as

    proxy_pass http://127.0.0.1:8080;

also has no effect.

Tried on Package nginx.x86_64 0:1.6.2-23.el6.art then updated to nginx.x86_64 0:1.8.0-1.el6.ngx – same effect…

UPD: seems like Apache uses whole request while nginx discards everything after #.

Best Answer

Your problem is that browsers don't even send the fragment identifier to the server, so even if Nginx was willing to rewrite based on that, it wouldn't be able to do so because it wasn't provided with that info.

I'm really curious about how your previous solution worked with Apache - I just double checked and my Firefox doesn't send the fragment identifier in the request (according to a packet capture). Maybe whatever browser you were using somehow behaved differently.

A potential solution would be to escape the hash character by URL-encoding it, which makes it become %23. You can use some Javascript to do the modification automatically on page load (check whether a fragment identifier is present, and if it is, convert it to %23 and refresh the page using the new URL). You would then need to rewrite based on that instead of the original hash character.