简体   繁体   中英

HTACCESS 404 error not working properly

The problem:

The requested URL /welcome.php was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

Here it goes:

  • When I go to www.mysite.com/page it works fine, it also works if I go to mysite.com/404

  • But, when I misspell something and go to www.mysite.com/pag (instead of 'page') I'll get the above error.

I'm also using PHP in my index file (welcome.php) to determine the $_GET value and dynamically display the correct page. It may have something to do with this.

Test site: http://mrobertsdesign.ca/home (you can see the error at http://mrobertsdesign.ca/hom )

I've looked everywhere for answers, been at this for the past 12 hours just trying to figure out why it isn't working. The bottom line is that I'm not sure what's causing the issue... All help is appreciated!

Any ideas??


My .htaccess file is:

<Files .htaccess>
order allow,deny
deny from all
</Files>

ErrorDocument 404 http://mrobertsdesign.ca/404

Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

RewriteCond %{HTTP_HOST} ^www\.mrobertsdesign\.ca [NC]
RewriteRule ^(.*)$ http://mrobertsdesign.ca/$1 [R=301]

RewriteRule ^([a-zA-Z0-9]+)/?$ welcome.php?page=$1 [NC]
RewriteRule ^([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ welcome.php?category=$1&page=$2 [NC]

DirectoryIndex comingsoon.php welcome.php

My index file is (welcome.php):

<?php 

    $web_url = "http://mrobertsdesign.ca";

    $path = '';
    $page = $_GET['page'];
    $pages = array('home','about','work','contact','404');

    if ((basename($_SERVER['__FILE__'])) == 'welcome.php'){
        if (!empty($page)) {
            $url = '/' . $page;
        } else {
            $page = 'home';
            $url = '/' . $page;
        }
        header('Location: ' . $url, true, 301); exit();
    }
    if (!empty($page)) {
        if(in_array($page,$pages)) {
            if (!empty($category)) {
                $path = $category . '/' . $category . '_' . $page;
            } else {
                $path = 'content_' . $page;
            }
        }else {
            $page = '404';
            $url = '/' . $page;
            header('Location: ' . $url, true, 404); exit();
        }
    }
    else {
        $page = 'home';
        $path = 'content_' . $page;
    }

              if($page == 'home'){
                    // stuff for home here
        }else if($page == 'about'){ 
                    $page_title = "About"; 
        }else if($page == 'work'){ 
                    $page_title = "Work"; 
        }else if($page == 'contact'){ 
                    $page_title = "Contact"; 
        }else if($page == '404'){ 
                    $page_title = "Oops! (404)"; 
        }
        $page_class = 'page-' . $page;

    // Page Start

    include('includes/header.php');
    include('includes/' . $path . '.php');
    include('includes/footer.php');
?>

When changing:

    else {
        $page = 'home';
        $url = '/' . $page;
    }

To this:

    else {
        http_response_code(404); exit; 
    }

The error changes to an internal server error for both welcome.php & the 404 error page:

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, cgiadmin@yourhostingaccount.com and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.


More info that I've observed:

  • My .htaccess file is rewriting values such as /welcome.php?page=about to /about and /welcome.php?category=about&page=me to /about/me , so if I go to /about it will go to the about page (and there is no /about/me or any second level of pages at all right now any ways).

  • If I misspell that and go to /abou or /anything-here or /anything-here/anything-here-too it displays the error saying that it can't find both my index (welcome.php) and my 404 error page.

  • However, if I go to /welcome.php?page=abo (instead of about , anything that isn't a real page) it displays my 404 error page.

  • If I go to /any-page.fileextention (eg. /about.php - which doesn't actually exist) it will display the 404 error page, also if I go to /one/two/three it will also display the 404 error page.

  • If you go to /welcome.php (my index page) it will show the correct page, and if you take out part of the file extension like /welcome.ph it will display the 404 error page. If you go to the 404 error page it also displays correctly at /404 .

The error seems to be fired when a file is being treated as a file system (eg. /about compared to /about.php or /welcome.php?page=about or /welcome.php?page=abo ) for up to two levels in (eg. /about and /about/me ).

In /welcome.php?page=mypage , the address literally already points to /welcome.php , but in /about the address is just a file system that the .htaccess file is supposed to interpret as the $_GET value for my /welcome.php page, which works when the $_GET value is a real value, but when it's not it comes back as an error and throws everything off.

The issue isn't even the error document at this point, it's that it can't find /welcome.php and /404 when the address is read as a file system with incorrect $_GET values... It's not trying to find /abou/welcome.php because there is a file extension and would be ultimately thrown to the real 404 page, and it's not trying to go to /abou/404 because in my .htaccess file I've provided the full path to my 404 page at http://mrobertsdesign.ca/404 . This is where I'm lost.

  • How does stackoverflow achieve what it's doing with it's .htaccess file where you can delete part of the url and it will try to either fill it in with the closest resembling url or throw a 404 error page?

The answer!

As @Phil_1984_ stated, the following line was conflicting with the ErrorDocument request, which caused the 404 not found error for my /welcome.php page and ErrorDocument request itself:

    else {
        $page = 'home';
        $url = '/' . $page;
    }

His initial idea was to change the line to the following:

    else {
        http_response_code(404); exit; 
    }

Which got me thinking, I already have the dynamic layout setup, I can just return the $_GET value to the page instead of trying to redirect the whole page to the 404 page - which it turns out is what was causing the issue.

The solution was, instead of trying to redirect the whole page (technically back on itself since the whole site is built up of this PHP script and a series of includes) to the 404 page, to just turn the value of $_GET back to $path so that the include file include('includes/' . $path . '.php'); would read it and just include the 404 document into the page (as it would be doing any ways, only difference is that the url doesn't change).

    else {
        $page = '404';
        $path = 'content_' . $page;
    }

From the Apache Docs:

https://httpd.apache.org/docs/2.2/custom-error.html

Make sure the path is correct and AllowOverride is enabled.

The answer!

As @Phil_1984_ stated, the following line was conflicting with the ErrorDocument request, which caused the 404 not found error for my /welcome.php page and ErrorDocument request itself:

    else {
        $page = 'home';
        $url = '/' . $page;
    }

His initial idea was to change the line to the following, which didn't work for me (through a 500 error):

    else {
        http_response_code(404); exit; 
    }

Which got me thinking, I already have the dynamic layout setup, I can just return the $_GET value to the page instead of trying to redirect the whole page to the 404 page - which it turns out is what was causing the issue.

The solution was, instead of trying to redirect the whole page (technically back on itself since the whole site is built up of this PHP script and a series of includes) to the 404 page, to just turn the value of $_GET back to $path so that the include file include('includes/' . $path . '.php'); would read it and just include the 404 document into the page (as it would be doing any ways, only difference is that the url doesn't change).

    else {
        $page = '404';
        $path = 'content_' . $page;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM