Laravel 7 - How to remove trailing slash URLs from my application? - php

I have already tried changing the .htaccess file, tried several solutions to it, nothing works. Whenever I add a trailing slash to the URL it opens another page, which should not happen, adding a trailing slash to the URL should redirect it to the URL without a trailing slash. I tried the following solutions:
Solution 1
Solution 2
What I want to achieve is http://127.0.0.1:8080/login/ should be redirected to http://127.0.0.1:8080/login for every URL in my application.
public/.htaccess
<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 Trailing Slashes
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
// Navigation Menu
Route::get('advisor', 'AdvisorController#index');
Route::get('investment', 'InvestmentController#index');
Route::get('investor', 'InvestorController#index');
Route::get('product', 'ProductController#index');
Route::get('rate', 'RateController#index');
// Stop registration other functions
Auth::routes([
'register' => false, // Registration Routes...
'reset' => false, // Password Reset Routes...
'verify' => false, // Email Verification Routes...
]);
// Login
Route::get('/', function () {
return redirect('login');
});
// Dashboard
Route::get('/home', 'HomeController#index')->name('home');
//admin users
Route::resource('/admin/users', 'Admin\UsersController', ['except' => ['show', 'create', 'store']]);
error screenshots:
Without trailing slash, my application URL:
Now if I add a trailing slash to the URL, I get this:

Finally, I was able to do it with middleware, editing the .htaccess somehow doesn't work locally or it's not working in my application, anyways, check the solution below:
if (preg_match('/.+\/$/', $request->getRequestUri()))
{
return Redirect::to(rtrim($request->getRequestUri(), '/'), 301);
}
reference
here

Related

Laravel routes in Shared Hosting not works properly

I'm with a problem very similar with this another question, but the solutions provided in that thread not helped me.
I made the deploy of my Laravel app to a shared hosting service using this guide (BTW, the guide is very similar to one of the answers of the linked question)
Below is my routes/web.php file
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::group(['prefix' => 'law', 'middleware' => ['ability:superadministrator,read-users|create-users']], function () {
Route::get('/search', 'LawController#showSearchView');
Route::get('/new', ['middleware' => ['permission:create-users'], 'uses' => 'LawController#showNewView']);
Route::get('/find', 'LawController#find');
Route::get('/edit/{id}', 'LawController#edit');
//region post
Route::post('/new', ['middleware' => ['permission:create-users'], 'uses' => 'LawController#store']);
Route::post('/search', ['middleware' => ['permission:read-users'], 'uses' => 'LawController#search']);
/*Route::post('/modify', ['middleware' => ['permission:create-users'], 'uses' => 'LawController#modify']);*/
//endregion
});
Route::group(['prefix' => 'user', 'middleware' => ['ability:superadministrator,read-users|create-users']], function () {
//..similar to the previous one
});
//some other route groups
The issue is, I can access the welcome page and also the login page. After authentication, I go to the home page and then the problem starts. Every other route than I try (like mydomain.net/law/search) leaves me to the home page again in some kind of infinity loop. The logout route also works fine.
Whats is strange to is that if I try a inexistent route like mydomain.net/blah, I go the the knowledge RouteNotFound/"NotFoundHttpException" of Laravel Framework.
I don't receive any error in php log or in my browser console. The javascript works fine.
I contact the support of the host service to ensure that Apache had the mod_rewrite enabled and apparently it is.
I googling for it about 3 hours and dig deeper here in SO, but anything helped me to understand the problem. Any tip?
Below is the .htacces file if it helps in any way:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
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}]
</IfModule>
MISC:
PHP 7.1
Laravel 5.4
The composer.json for reference
I'm using the Laravel AdminLTE and the sidebar menu also does not work properly. I think that is the same problem causing the both issues.
My .env file does not have anything special, but here is (part of) it.
Add this in your .htaccess file
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [L]
This rule will internally load content of REQUEST_URI to the index.php

Laravel group route issue

I'm using this code to implement admin area routes but Route::get('/',...) doesn't work, it seems I should use anything other than / in get ,otherwise laravel doesn't load view when I browse to mysite/admin/.
Route::group(['prefix' => 'admin', 'namespace' => 'admin', 'as' => 'admin'], function() {
Route::get('/', function() {
return view('backend.index');
});
Route::resource('post', 'PostController');
});
UPDATE: there is an admin folder in public that is public/admin. It seems Laravel open this directory instead of going through the route !
is it normal ? does public folder structure has priority to Route::get() ?
If you have admin folder inside public folder it's normal that this directory content will be displayed but it's not Laravel issue.
If you look in public/.htaccess you have there something like this:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
so if directory or file exists in public directory Laravel will not launch application but server will display this directory or this file. This is what should be done, because if there wouldn't be such rule no CSS files, JavaScript files or images could be displayed.
What you should do is either change directory name in public folder from admin to something else (and then make changes in your code to reflect this change) or change admin route to something else

laravel 5 main domain with www and also recognize sub domains

I have domain as example.dev and i want to redirect it to www.example.dev in laravel 5. In local environment i have setup virtual host as example.dev and also setup it's alias as www.example.dev.
my .htaccess file on laravel 5 looks like this.
<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]
</IfModule>
RewriteBase "/"
and my routes file in laravel looks like this.
Route::group(array('domain' => 'example.dev'), function()
{
Route::get('/', function() {
return "I'm root!";
});
});
Route::group(array('domain' => '{sub}.example.dev'), function()
{
Route::get('/', function($sub) {
return "I'm ".$sub." subdomain";
});
});
now if i visit at example.dev, i get output as
I'm root
and if i visit at something.example.dev, i get
I'm something subdomain
and if i visit at www.example.dev, i get this...
I'm www subdomain
what i could think of is to define another custom domain group with www but this is not so good i believe or not good practice. i tried with some modification in my .htaccess file as follow after RewriteEngine On
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L,R=301]
and now if i visit example.dev it redirect be at www.example.dev but still the output is
I'm www subdomain
then i changes my first routing group from example.dev to www.example.dev and it worked! but i just need to know if this is the right way to do this or not? or using groups for multiple sub-domains is the only way ? and do you know any easy and best way to check subdomains from database through controller so i will check it that subdomain exists then serve with it's view otherwise pass not found error. i know somewhere it can be done with filter and using before but don't know exactly!
help would be really appreciated.
thanks :)
Route::group(array('domain' => '{sub}.example.dev'), function($sub)
{
if($sub == 'www' || $sub == ''){
Route::get('/',function(){
return "I'm root!";
});
}
else{
Route::get('/', function($sub) {
return "I'm ".$sub." subdomain";
});
}
});

Laravel default route for subdirectory in a route group with prefix

I have a route group for the prefix admin. I want that if the URL http://www.example.com/admin/ is entered it by default loads the login page residing at http://www.example.com/admin/login. The login page is actually a controller, but I don't mind if the admin/ redirects to admin/login or routes to its controller directly. From other answers I saw here it seems that redirection is better to make sure links are not messed up.
I have tried various solutions with both routing and redirection, including the solution suggested here but I am alwas getting Error 404. What is the recommended proper way to achieve this?
My route group looks like this:
Route::group(array('prefix' => 'admin', 'namespace' => 'MyNamespace\Controllers\Admin'), function()
{
//the following work fine
Route::get('login', array('uses' => 'AdminLoginController#showLogin'));
Route::post('login', array('uses' => 'AdminLoginController#doLogin'));
Route::get('logout', array('uses' => 'AdminLoginController#doLogout'));
//other resource routes for the respective admin pages
});
Outside the route group I added the following, so that even http://www.example.com/admin without the trailing slash goes to the login page, which works fine.
Route::get('admin', function() { return Redirect::to("admin/login"); });
The problem is with http://www.example.com/admin/ that is giving Error 404. I tried all the following (separately obviously), and none works. All of them were inside the route group.
Route::get('/', function() { return Redirect::to("admin/login"); });
Route::get('', function() { return Redirect::to("admin/login"); });
Route::get('/', function() { return Redirect::to("login"); });
Route::get('', function() { return Redirect::to("login"); });
Route::get('/', array('uses' => 'AdminLoginController#showLogin'));
Route::get('', array('uses' => 'AdminLoginController#showLogin'));
I also tried this outside the route group:
Route::get('admin/', function() { return Redirect::to("admin/login"); });
None of them work. What is the right way to set a default route for a route group with a prefix subdirectory?
use this code in .htaccess
so your server will redirect url's with trailing slashes to url without.
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
# redirect everything to url without trailing slash
RewriteCond %{HTTPS} =on
RewriteRule ^(.+)$ - [env=ps:https]
RewriteCond %{HTTPS} !=on
RewriteRule ^(.+)$ - [env=ps:http]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_METHOD} ^GET
RewriteRule ^(.+)/$ %{ENV:ps}://%{SERVER_NAME}/$1 [R=301,L]
# pretty urls
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
</IfModule>
by default laravel firstly did redirection, but later was removed.

Subdomains in Laravel

Having problem with subdomains :(
In Routes:
Route::group(['domain' => 'www.app.me'], function(){
Route::get('/', 'SiteController#index');
Route::get('/{uri}', 'ShortnerController#redirect');
});
Route::group(['domain' => 'app.me'], function(){
Route::get('/', 'SiteController#index');
Route::get('/{uri}', 'ShortnerController#redirect');
});
Route::group(['domain' => 'platform.app.me'], function(){
Route::get('/', 'PageController#index')->before('auth');
});
Route::group(array('domain'=>'agent.app.me'), function(){
Route::get('/', 'AgentController#index')->before('auth');
});
When I go to app.me or www.app.me it shows the SiteController#index
If I go to agent.app.me it shows AgentController#index
But the problem is if I go to platform.app.me it redirects to app.me
How to solve this?
In cPanel a managed redirections like this:
Subdomains.Root Domain Document Root Redirection
agent.app.me /public_html not redirected
platform.app.me /public_html not redirected
Try changing the order. The first matched route will always be the one used. Also, if app.me is just going to use the same routes as www., why not use htaccess to force www. and have one less route group to maintain?
So, routes.php:
Route::group(['domain' => 'platform.app.me'], function(){
Route::get('/', 'PageController#index')->before('auth');
});
Route::group(['domain'=>'agent.app.me'], function(){
Route::get('/', 'AgentController#index')->before('auth');
});
Route::group(['domain' => 'www.app.me'], function(){
Route::get('/', 'SiteController#index');
Route::get('/{uri}', 'ShortnerController#redirect');
});
Notice that I changed your use of array() to [] in the agent.app.me route group for consistency as you were mixing the two.
And .htaccess:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
# Enforce www where not using www or a valid sub domain or tld
RewriteCond %{HTTP_HOST} !^(www|agent|platform)\.app\.(me|dev)$ [NC]
RewriteRule ^(.*)$ http://www.app.me/$1 [L,R=301]
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

Categories