How to get .htaccess to attach REQUEST_URI to 404 page
Asked Answered
B

6

9

Is there a way to send the request URI along to the 404 page as a URL variable? For instance, if I forward my 404's with an ErrorDocument directive, is there a way to do something like this? This is the code I tried but it obviously didn't work.

ErrorDocument 404 /pages/errors/index.php?e=404&url=%{REQUEST_URI}

I also tried a mod_rewrite, but I couldn't get that working either. Here is what I tried with mod_rewrite:

Options +FollowSymLinks
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /pages/errors/index.php?e=404&url=%{REQUEST_URI} [L,R=404]

Basically all I'm trying to do is so that when a user types in something like http://mysite.com/asdf then it forwards to http://mysite.com/pages/errors/index.php?e=404&url=/asdf assuming that the directory /asdf does not exist on the server.

Is there an easy way to achieve this?

Bison answered 26/1, 2013 at 1:52 Comment(2)
Could you try using a redirect and then checking the referrer on the 404 php?Glochidium
I tried that and $_SERVER['REQUEST_URI'] but neither worked, they both just came up blank.Bison
S
4

I don't think you have to pass any additional information to the error handler script, if that's what your question is about. Apache supplies enough information:

Redirecting to another URL can be useful, but only if some information can be passed which can then be used to explain or log the error condition more clearly.

To achieve this, when the error redirect is sent, additional environment variables will be set, which will be generated from the headers provided to the original request by prepending 'REDIRECT_' onto the original header name. This provides the error document the context of the original request.

For example, you might receive, in addition to more usual environment variables, the following.

REDIRECT_HTTP_ACCEPT=/, image/gif, image/jpeg, image/png

REDIRECT_HTTP_USER_AGENT=Mozilla/5.0 Fedora/3.5.8-1.fc12 Firefox/3.5.8

REDIRECT_PATH=.:/bin:/usr/local/bin:/sbin

REDIRECT_QUERY_STRING=

REDIRECT_REMOTE_ADDR=121.345.78.123

REDIRECT_REMOTE_HOST=client.example.com

REDIRECT_SERVER_NAME=www.example.edu

REDIRECT_SERVER_PORT=80

REDIRECT_SERVER_SOFTWARE=Apache/2.2.15

REDIRECT_URL=/cgi-bin/buggy.pl

REDIRECT_ environment variables are created from the environment variables which existed prior to the redirect. They are renamed with a REDIRECT_ prefix, i.e., HTTP_USER_AGENT becomes REDIRECT_HTTP_USER_AGENT.

REDIRECT_URL, REDIRECT_STATUS, and REDIRECT_QUERY_STRING are guaranteed to be set, and the other headers will be set only if they existed prior to the error condition.

None of these will be set if the ErrorDocument target is an external redirect (anything starting with a scheme name like http:, even if it refers to the same host as the server).

Check this link

Slashing answered 26/1, 2013 at 2:17 Comment(0)
I
2

I think you need to remove R=404. This worked for me;

Options +FollowSymLinks
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php?e=404&url=%{REQUEST_URI} [L]

Tests: foo/index.php : print_r($_GET)

localhost/foo -> Array ( )

localhost/foo/asdf -> Array ( [e] => 404 [url] => /foo/asdf )

Intercommunicate answered 26/1, 2013 at 2:38 Comment(1)
The R=404 flag would result in the substitution being ignored and would trigger an internal subrequest to the Apache 404 error document.Urine
B
1

Your first attempt of putting %{REQUEST_URI} in the ErrorDocument directive should now work in a recent version of Apache. From https://httpd.apache.org/docs/2.4/mod/core.html#errordocument:

From 2.4.13, expression syntax can be used inside the directive to produce dynamic strings and URLs.

Blankly answered 30/6, 2020 at 13:57 Comment(0)
C
0

I have another idea, since you're using php, why not just access $_SERVER['HTTP_REFERER']. That shows you previous page request, so presumably it would be exactly what you're looking for. From there, you can do what you want with that value. Does that work?

Clepsydra answered 26/1, 2013 at 1:59 Comment(3)
I tried that and $_SERVER['REQUEST_URI'] but neither worked, both just turned out blank.Bison
@danL Reading this comment, and instead of posting an "answer" to this one comment, I typed out some code in pastebin, to troubleshoot your problems with $_SERVER.. pastebin.com/c5U6bTMcEstragon
I actually got it to work by using $_SERVER['REDIRECT_URL']. Thanks, though!Bison
C
0

You are alreay checking file/folder existing before rewriterule by rewritecond, you don't need to use request uri in rewrite rule and handle it by $_SERVER['REQUEST_URI']

Options +FollowSymLinks
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /pages/errors/index.php?e=404 [L,R=404]
Cassius answered 26/1, 2013 at 2:10 Comment(0)
F
0

Finally got this working, albeit a bit unconventionally. I'm running on ColdFusion instead of PHP and the other answers here didn't work for me, unfortunately. But I think this will work for anyone regardless of their server-side platform because it's javascript based:

In .htaccess:

ErrorDocument 404 /mark404.cfm

In /mark404.cfm

<script>
   window.location = '/handle404.cfm';
</script>

In /handle404.cfm

<script>
    var r = document.referrer;
    //this is what you want, the url that the user tried to hit
</script>

Reason this works is the browser still "thinks" it's on the requested doesntexist.html when it hits mark404. So when you redirect to handle404, doesntexist.html is in the browser history and javascript can pick it up.

Furculum answered 13/11, 2015 at 4:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.