2

How can I pass the 404'd URL to my 404.html page using .htaccess

For example, if I visit an invalid page: /user/123

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
ErrorDocument 404 /?404.php?error_path={???}
                                         ^
=========================================^ 

Resulting in a 404 redirect to /404.php?error_path=/user/123

d-_-b
  • 21,536
  • 40
  • 150
  • 256

3 Answers3

4

ErrorDocument is not part of mod_rewrite and that is invalid. Is this what your looking for?

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Rewriterule ^(.*) /404.php?error_path=$1 [R=301,L]
Panama Jack
  • 24,158
  • 10
  • 63
  • 95
  • Downvoter want to explain? The OP was using errordocument incorrectly. – Panama Jack Mar 16 '15 at 13:21
  • Whilst this makes the mod_rewrite code "technically valid", it's arguably not how a 404 error document should be triggered (with an external redirect). If you did want to trigger the 404 with mod_rewrite, then the custom `ErrorDocument` should still be defined and trigger it like: `RewriteRule ^ - [R=404,L]`. Although mod_rewrite would seem to be unnecessary here. (I wasn't the downvoter btw.) – MrWhite Dec 27 '16 at 00:48
  • @w3dk yes but the OP asked for a specific way of doing something and that was redirecting to his 404.php page. A redirect of course will do that. Regardless of this being the best way or not, I provided what I "thought' he asked for. – Panama Jack Dec 27 '16 at 13:26
3

On apache 2.4 and later, you can use mod-rewrite variables with ErrorDocument directive :

ErrorDocument 404 /404.php?uri=%{REQUEST_URI}

This will internally send the 404 uri to your 404.php page and you can manipulate it using the following code in 404.php

<?php
echo "the broken uri is $_GET['uri']";
?>
Amit Verma
  • 40,709
  • 21
  • 93
  • 115
  • You don't need to explicitly pass the URL to the defined ErrorDocument. You can simply access the PHP superglobal `$_SERVER['REQUEST_URI']` (or `$_SERVER['REDIRECT_URL']`) directly in the error document. – MrWhite Dec 27 '16 at 00:26
1

You can't append the path of the site which threw the error to the URL of the displayed error page using the ErrorDocument directive. However as you're working with PHP you could use the global $_SERVER["REDIRECT_URL"] value from within your error handling script.

See http://httpd.apache.org/docs/current/custom-error.html#variables for more 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).

Zepporle
  • 413
  • 4
  • 13
  • If you are doing any internal rewriting then it might be preferable to present `$_SERVER['REQUEST_URI']` in the error that the user sees, rather than `REDIRECT_URL`. The former will hold the actual URI the _user_ requested (before being rewritten). Whereas `REDIRECT_URL` holds the URL _after_ rewriting and that ultimately resulted in the error document being triggered - useful to the developer, but possibly confusing for the end user. – MrWhite Dec 27 '16 at 00:33