如何在Laravel生成的URL中去除"public/index.php"?

105
我需要在Laravel中从生成的URL中移除index.phppublic/index.php,通常路径是localhost/public/index.php/someWordForRoute,应该变成localhost/someWordForRoute.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>

RewriteEngine On

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

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

app/config/app.php

'url' => 'http://localhost',

我怎么能改变那个?


7
在Laravel中使用漂亮的URL,确保启用了mod_rewrite - Kryten
1
https://dev59.com/cWEi5IYBdhLWcg3wFoy9#21662885 - The Alpha
2
这是另一种解决方法,当其他解决方法无效时可尝试使用:http://www.dev-metal.com/enable-mod_rewrite-ubuntu-14-04-lts/ - TuGordoBello
你也可以像这样移动文件:https://youtu.be/ybJYyU5FPv4 - MD Singh
1
重新开放投票者:这个问题从根本上是错误的,并且源于网络服务器的错误配置。唯一正确的解决方案是将网络服务器的文档根目录设置为公共目录。这里所有得票最高的答案都会带来潜在的安全问题并鼓励不良实践,这就是为什么我将其标记为一个重复问题的原因,而那个问题的最佳答案才是正确的解决方案。 - miken32
显示剩余3条评论
19个回答

152

选项1:使用.htaccess文件

如果不存在,请在Laravel根目录中创建一个.htaccess文件。 如果您的Laravel根目录中没有.htaccess文件,请创建一个。(通常位于您的public_html文件夹下)

编辑.htaccess文件,使其包含以下代码:

<IfModule mod_rewrite.c>
   RewriteEngine On 
   RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
现在,您应该能够访问网站而不需要"/public/index.php/"的部分。
选项2:将“/public”目录中的内容移动到根目录中
在根目录中创建一个新文件夹,并将除public文件夹外的所有文件和文件夹移动到其中。您可以自己取任何名称,我将使用“laravel_code”。
接下来,将public目录中的所有内容移到根文件夹中。它应该结果与此类似: enter image description here 之后,我们只需编辑laravel_code/bootstrap/paths.php文件和index.php文件中的位置即可。
laravel_code/bootstrap/paths.php中找到以下代码行:
'app' => __DIR__.'/../app',
'public' => __DIR__.'/../public',

然后将它们更改为:

'app' => __DIR__.'/../app',
'public' => __DIR__.'/../../',

index.php中,找到以下这几行代码:

require __DIR__.'/../bootstrap/autoload.php';     
$app = require_once __DIR__.'/../bootstrap/start.php';

并将它们改为:

require __DIR__.'/laravel_code/bootstrap/autoload.php';     
$app = require_once __DIR__.'/laravel_code/bootstrap/start.php';

来源:如何在Laravel中删除URL中的/public/


7
如果您使用Debian Linux,请不要忘记编辑 etc/apache2/apache2.conf 文件,在 <Directory /var/www/></Directory> 目录配置处,将 AllowOverride None 更改为 AllowOverride All。请注意,不要改变原来的意思,并尽可能使语言更加通俗易懂。 - Robin Hood
1
我只需要将 .htaccess 文件添加到我的根目录中就可以让它工作了。 - Mário Rodrigues
12
在生产模式下,将工作目录切换到 /root 并不是一个好的建议!公共文件夹存在的原因是有其合理性的。 - toesslab
为确保重写规则正常工作,请检查 Apache 配置 <Directory ... 配置是否具有 AllowOverride All'。类似这样:<Directory "/var/www/html/laravel/public"> Options Indexes FollowSymLinks MultiViews **AllowOverride All** </Directory> - Japheth Ongeri - inkalimeva
1
绝对不行。永远不要那样做。 - Daniel Steiner
显示剩余4条评论

43

我在Laravel 4.2上尝试了这个方法

将Laravel根目录下的server.php文件重命名为index.php,并将/public目录下的.htaccess文件复制到Laravel根目录下。

希望这样可以解决问题。


2
如果Luazan提供的答案无效,那么这个方法就足够了。不过我建议编辑public文件夹中的index.php文件,以便在用户直接访问该链接时将其重定向到public之外。 - Brad Bird
4
JS和CSS文件不再从公共文件夹加载。 - llioor
@MaHDyfo - 为什么它不安全?以及为什么不安全? - 151291
2
@151291 因为 .env 文件可以被访问你的网站的所有人,除非你保护好你的 Web 服务器以避免这种情况。 - Mahdyfo

23

不要因为其他选项而感到困惑,下面的代码片段是我正在使用的,并且对您也有用。 将以下htaccess放在您的根目录中。

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteRule    ^$    public/    [L]
    RewriteRule    (.*) public/$1    [L]
</IfModule>

前往您的公共目录,放置另一个带有下面代码片段的htaccess文件

<IfModule mod_rewrite.c>
    RewriteEngine On
    # Removes index.php from ExpressionEngine URLs  
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?url=$1 [PT,L]

</IfModule>

它正在工作... !!!

Laravel使用以下.htaccess文件

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

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

很好:你能告诉我这种方法的优缺点吗? - Muhammad Ateek
我只编辑了根目录下的 .htaccess 文件(你提供的第一个片段),这样问题就解决了,谢谢! - peird
在 Laravel 9 中,这是唯一的选项。 - Shalin Nipuna

15

1) 检查mod_rewrite是否已启用。前往/etc/apache2/mods-enabled目录,查看rewrite.load是否可用。如果不可用,则使用命令sudo a2enmod rewrite进行启用。这将启用重写模块。如果已经启用,则会显示消息Module rewrite already enabled
2) 为公共目录创建虚拟主机,以便我们可以使用http://example.com/index.php, 而不是http://localhost/public/index.php。[因此隐藏了public文件夹名称]
3) 然后在根目录(public文件夹内)创建.htaccess文件,该文件将从您的URL中隐藏index.php。

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]

1
尝试了你的步骤,但还没有得到结果!我不知道为什么会这样发生! - Mostafiz Rahman
请提供日志信息以便我们跟踪根本原因。 - Orchid
以下是完整的日志文件链接:https://www.dropbox.com/s/8fhlbej86nqr5qj/laravel.log?dl=0 - Mostafiz Rahman
对我有用。不要让虚拟主机直接指向公共文件夹。 - cardi777
谢谢。这对我有用,我的 mod_rewrite 被禁用了。 - Maubeh

13

这里是删除URL中public的简单步骤(Laravel 5)

1: 复制public文件夹中的所有文件,并将它们粘贴到Laravel根目录中

2: 打开index.php并更改

 require __DIR__.'/../bootstrap/autoload.php';

To

 require __DIR__.'/bootstrap/autoload.php';

And
$app = require_once __DIR__.'/../bootstrap/app.php';


$app = require_once __DIR__.'/bootstrap/app.php';

在 Laravel 4 中,路径2是 $app = require_once __DIR__.'/bootstrap/start.php';,而不是 $app = require_once __DIR__.'/bootstrap/app.php';/app.php

就这样了。


网站的其他链接方面是否存在其他复杂性? - Haring10
看起来这是一个非常棒的解决方案,同时也很简单。但是正如Haring10所说,真的没有任何问题吗? - Peter

7

对于 Laravel 4 和 5:

  1. 将 Laravel 根目录中的 server.php 文件重命名为 index.php
  2. /public 目录下的 .htaccess 文件复制到 Laravel 的根目录下。

就这么简单!:)


5
这可能与Laravel无关,而与你的Apache配置有关。你能访问你的Apache服务器配置吗?如果可以的话,请查看文档中的以下内容:
一般情况下,只有在没有访问主服务器配置文件时才应使用.htaccess文件。例如,普遍存在这样的误解:用户身份验证应始终在.htaccess文件中完成,近年来又出现了模糊认识,即mod_rewrite指令必须放在.htaccess文件中,但事实并非如此。你可以将用户身份验证配置放在主服务器配置文件中,这实际上是首选的方法。同样,就许多方面而言,mod_rewrite 指令在主服务器配置中更有效。
总的来说,应尽可能避免使用.htaccess文件。任何你考虑放在.htaccess文件中的配置都可以在你的主服务器配置文件中的section部分中同样有效地实现。
来源:Apache文档
我之所以首先提到这一点,是因为如果可能的话最好完全摒弃.htaccess,并使用VirtualHost标签内的Directory标签。话虽如此,接下来的内容将假定你出于某些原因而坚持使用.htaccess路线。
具体而言,可能会发生以下几种情况:
  1. I note, perhaps pointlessly, that your file is named .htacces in your question. My guess is that it is a typo but on the off chance you overlooked it and it is in fact just missing the second s, this is exactly the sort of minor error that would leave me banging my head against the wall looking for something more challenging.

  2. Your server could not be allowing .htaccess. To check this, go to your Apache configuration file. In modern Apache builds this is usually not in one config file so make sure you're using the one that points to your app, wherever it exists. Change

    AllowOverride none
    

    to

    AllowOverride all
    

    As a followup, the Apache documents also recommend that, for security purposes, you don't do this for every folder if you are going to go for .htaccess for rewriting. Instead, do it for the folders you need to add .htaccess to.

  3. Do you have mod_rewrite enabled? That could be causing the issues. I notice you have the tag at the top <IfModule mod_rewrite.c>. Try commenting out those tags and restart Apache. If you get an error then it is probably because you need to enable mod_rewrite: How to enable mod_rewrite for Apache 2.2

希望这能帮到你。我列举了一些常见问题,但还有其他一些可能更琐碎或独特的问题。对于开发服务器的另一个建议?重新安装Apache。如果可能的话,从不同的来源进行,并使用好的教程进行操作。

Apache2配置设置的捕获很棒,我每次都会错过这个设置。 - Abhishek

5

在编辑.htaccess文件后,请确保Rewrite引擎已打开。

sudo a2enmod rewrite

很好的观察。我在一台新服务器上,实际上需要启用它(并在Apache配置中添加必要的部分),使用以下链接进行操作:https://www.digitalocean.com/community/tutorials/how-to-rewrite-urls-with-mod-rewrite-for-apache-on-debian-9 - cdsaenz

2

创建一个名为 .htaccess 的新文件,并添加以下内容即可解决问题。

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

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ ^$1 [N]

RewriteCond %{REQUEST_URI} (\.\w+$) [NC]
RewriteRule ^(.*)$ public/$1 

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ server.php

我相信这个问题会被解决,因为我遇到过类似的问题,而且都是通过这种方式解决的。

谢谢。


2
您需要执行以下步骤才能完成此操作,具体如下:
  • 将您的域名映射到项目的公共文件夹中(即 /var/www/html/yourproject/public)(如果使用 Linux)

  • 进入您的公共文件夹并编辑其中的 .htaccess 文件

AddHandler application/x-httpd-php72 .php
<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect non-www to www
    RewriteCond %{HTTP_HOST} !^www\.
    RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

    # Redirect non-http to https
    RewriteCond %{HTTPS} off
    RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

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

    # Remove index.php
    RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
    RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
</IfModule>


  • 如果您直接访问任何路由而没有使用 https,最后三条规则将保护您。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接