Laravel route strange behavior

2019-08-27 16:32发布

The following code

Route::get('test/{n}', function ($n) {
    return $n;
});

App::missing(function () {
    return Response::make("Dude, that's a 404 !", 404);
});

works with anything like

http://localhost/myproject/public/test/something

but

http://localhost/myproject/public/test/

redirects to

http://localhost/test

I believe it should instead display

Dude, that's a 404 !

I might have missearched the SO forum, but does anyone have an explanation on this strange behavior ?

EDIT : @Mohammad Walid

Okay, so, I changed my routes.php to this :

Route::get('/', 'HomeController@showWelcome');

Route::get('test', function () {
    return 'test';
});

App::missing(function () {
    return Response::make("Dude, that's a 404 !", 404);
});

I have not removed the line you talked about in public/.htaccess.

This works :

base_url/test

But this doesn't (redirects to localhost/test) :

base_url/test/

How can that be, since you said that removing the line would remove that feature ?

EIDT 2 :

Since it turns out that the problem comes from MAMP not interpreting the trailing slashes redirect condition correctly, a bug report was created in the MAMP bug base :

http://bugs.mamp.info/view.php?id=4586

1条回答
Root(大扎)
2楼-- · 2019-08-27 17:12

Its' because Laravel by default redirects trailing slashes.

In app/public/.htaccess file you can find the following:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301] #This line causes the problem

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

Change it to:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

Have a look at trailing slashes discussion.

Note if you remove the previous line your application won't be able to handle trailing slashes. Ex. if you have a route

Route::get('test', function() {
    return 'test';
}

Assume base_url/test/ has been requested instead of base_url/test the server will respond with 404 status.

Update

It seems that this is an issue only happens in local development (I use XAMPP).

The expected result for that rule is the following:

.htaccess
RewriteRule ^(.*)/$ /$1 [L,R=301]

Input (request)
http://localhost/website/test/

Output (after redirect)
http://localhost/website/test

But what we actually have in local development:

.htaccess
RewriteRule ^(.*)/$ /$1 [L,R=301]

Input (request)
http://localhost/website/test/

Output (after redirect)
http://localhost/test #this is wrong, according to the rule above it should redirects to http://localhost/website/test

So what you'll have if you remove the rule:

Request
http://localhost/website/test

Response
test


Request
http://localhost/website/test/

Response
Status 404
Dude, that's a 404 !

The expected response:
test

That's what I meant by

your application won't be able to handle trailing slashes.

the server will respond with 404 status.

I have tested the rule with online htaccess tester and it worked as expected, that's why I suppose the problem only exists in local development. Online test snapshot

查看更多
登录 后发表回答