Laravel 5 – Remove Public from URL

后端 未结 30 1922
甜味超标
甜味超标 2020-11-22 03:20

I know this is a very popular question but I haven\'t been able to find a working solution for Laravel 5. I\'ve been trying to migrate from Codeigniter for a long time, but

相关标签:
30条回答
  • 2020-11-22 03:42
    <IfModule mod_rewrite.c>
        <IfModule mod_negotiation.c>
            Options -MultiViews -Indexes
        </IfModule>
    
        RewriteEngine On
    
        # Handle Authorization Header
        RewriteRule ^(.*)$ public/$1 [L]
        RewriteCond %{HTTP:Authorization} .
        RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    
        # 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]
    </IfModule>
    

    Activate the mod_rewrite module with

    sudo a2enmod rewrite
    

    and restart the apache

    sudo service apache2 restart
    

    To use mod_rewrite from within .htaccess files (which is a very common use case), edit the default VirtualHost with

    sudo nano /etc/apache2/sites-available/000-default.conf
    

    Below "DocumentRoot /var/www/html" add the following lines:

    <Directory "/var/www/html">
    AllowOverride All
    </Directory>
    

    Restart the server again:

    sudo service apache2 restart
    
    0 讨论(0)
  • 2020-11-22 03:45

    Laravel 5.5

    After having installed Laravel for the first time, I faced the renowned "public folder problem" and I came up with this solution that, in my personal opinion, is "cleaner" then the others I found on the Web.


    Achievements

    • Don't have public word in the URI
    • Protect the .env file against curious people

    Everything can be done just editing the .htaccess using mod_rewrite and four simple rules.


    Steps

    1. Move the .htaccess file in public/.htaccess in the main root
    2. Edit it as below

    I commented everything, so it should be clear (I hope) also to those who have never used mod_rewrite (not that I'm an expert, all the opposite). Also, to understand the rules, it must be clear that, in Laravel, if Bill connects to https://example.com, https://example.com/index.php is loaded. This file just contains the command header("refresh: 5; https://example.com/public/"), which sends the request to https://example.com/public/index.php. This second index.php is responsible to load the controller and other stuff.

    # IfModule prevents the server error if the app is moved in an environment which doesn’t support mod_rewrite
    <IfModule mod_rewrite.c>
        <IfModule mod_negotiation.c>
            Options -MultiViews
        </IfModule>
    
        RewriteEngine On
    
        # RULES ORIGINALLY IN public/.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]
    
        # Handle Authorization Header
        RewriteCond %{HTTP:Authorization} .
        RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
        # --- END
    
        # PERSONAL RULES ---
        # All the requests on port 80 are redirected on HTTPS
        RewriteCond %{SERVER_PORT} ^80$
        RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
    
        # When .env file is requested, server redirects to 404
        RewriteRule ^\.env$ - [R=404,L,NC]
    
        # If the REQUEST_URI is empty (means: http://example.com), it loads /public/index.php
        # N.B.: REQUEST_URI is *never* actually empty, it contains a slash that must be set as match as below
        # .* means: anything can go here at least 0 times (= accepts any sequence of characters, including an empty string)
        RewriteCond %{REQUEST_URI} ^/$
        RewriteRule ^(.*) /public/index.php [L]
    
        # If the current request is asking for a REQUEST_FILENAME that:
        # a) !== existent directory
        # b) !== existent file
        # => if URI !== css||js||images/whatever => server loads /public/index.php, which is responsible to load the app and the related controller
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule !^(css|js|images|media)/(.*)$ /public/index.php [L,NC]
    
        # If the current request is asking for a REQUEST_FILENAME that:
        # a) !== existent directory
        # b) !== existent file
        # => if URI == css||js||images[=$1]/whatever[=$2] => server loads the resource at public/$1/$2
        # If R flag is added, the server not only loads the resource at public/$1/$2 but redirects to it
        # e.g.: bamboo.jpg resides in example.com/public/media/bamboo.jpg
        #       Client asks for example.com/media/bamboo.jpg
        #       Without R flag: the URI remains example.com/media/bamboo.jpg and loads the image
        #       With R flag: the server redirects the client to example.com/public/media/bamboo.jpg and loads the image
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^(css|js|images|media)/(.*)$ /public/$1/$2 [L,NC]
        # --- END
    
    </IfModule>
    

    The following rule (originally in public/.htaccess) can be deleted. The same rule, in fact, is explicited in a more detailed way in the last two rules.

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

    EDIT: I missed Abhinav Saraswat's solution and his answer should be the accepted one. Just one, simple and clear rule that redirects all the traffic to the public folder without modifying any file.

    0 讨论(0)
  • 2020-11-22 03:47

    Here is the Best and shortest solution that works for me as of may, 2018 for Laravel 5.5

    1. just cut your .htaccess file from the /public directory to the root directory and replace it content with the following code:

      <IfModule mod_rewrite.c>
          <IfModule mod_negotiation.c>
             Options -MultiViews
          </IfModule>
      
          RewriteEngine On
      
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteRule ^(.*)/$ /$1 [L,R=301]
      
          RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.gif|robots\.txt)$ [NC]
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteRule ^ server.php [L]
      
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_URI} !^/public/
          RewriteRule ^(css|js|images)/(.*)$ public/$1/$2 [L,NC]
      </IfModule>
      
    2. Just save the .htaccess file and that is all.

    3. Rename your server.php file to index.php. that is all enjoy!

    0 讨论(0)
  • 2020-11-22 03:48

    Easy way to remove public from laravel 5 url. You just need to cut index.php and .htaccess from public directory and paste it in the root directory,thats all and replace two lines in index.php as

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

    Note: The above method is just for the beginners as they might be facing problem in setting up virtual host and The best solution is to setup virtual host on local machine and point it to the public directory of the project.

    0 讨论(0)
  • 2020-11-22 03:48

    I would like to add to @Humble Learner and note that the proper location to "fix" the url path for assets is /Illuminate/Routing/UrlGenerator.php/asset().

    Update the method to match:

    public function asset($path, $secure = null)
    {
        if ($this->isValidUrl($path)) return $path;
        $root = $this->getRootUrl($this->getScheme($secure));
        return $this->removeIndex($root).'/public/'.trim($path, '/');
    }
    

    This will fix scripts, styles and image paths. Anything for asset paths.

    0 讨论(0)
  • 2020-11-22 03:49

    For XAMPP user to remove public from url without touching laravel default filesystem is to set a Virtual Host for your application to do this jsut follow these steps

    1. Open the XAMPP control panel application and stop Apache. Be aware that late Windows machines might run it as a service, so check the box to the left of the Apache module.

    2. Navigate to C:/xampp/apache/conf/extra or wherever your XAMPP files are located.

    3. Open the file named httpd-vhosts.conf with a text editor.

    4. Around line 19 find # NameVirtualHost *:80 and uncomment or remove the hash.

    5. At the very bottom of the file paste the following code:

    <VirtualHost *>
        ServerAdmin admin@localhost.com
        DocumentRoot "C:/xampp/htdocs" # change this line with your htdocs folder
        ServerName localhost
        ServerAlias localhost
        <Directory "C:/xampp/htdocs">
            Options Indexes FollowSymLinks Includes ExecCGI
            Order allow,deny
            Allow from all
        </Directory>
    </VirtualHost>
    
    1. Now you can copy and paste the code above below to add your Virtual Host directories. For example I’m working on a site called Eatery Engine so the following snippet will allow me to work with sub-domains on my local install:
    <VirtualHost eateryengine.dev>
        ServerAdmin admin@localhost.com
        DocumentRoot "C:/xampp/htdocs/eateryengine" # change this line with your htdocs folder
        ServerName eateryengine.dev
        ServerAlias eateryengine.dev
        <Directory "C:/xampp/htdocs/eateryengine">
            Order allow,deny
            Allow from all
        </Directory>
    </VirtualHost>
    
    1. Next head over to your Windows host file to edit your HOSTS. the file will be located at C:/Windows/System32/drivers/etc/hosts, where hosts is the file. Open it with notepad.
    2. Look for #localhost name resolution is handled within DNS itself.

    127.0.0.1 localhost

    localhost name resolution is handled within DNS itself.

    127.0.0.1       localhost
    127.0.0.1       eateryengine.dev #change to match your Virtual Host.
    127.0.0.1       demo.eateryengine.dev #manually add new sub-domains.
    
    1. Restart Apache and test everything.

    The original article can be found here

    0 讨论(0)
提交回复
热议问题