Laravel Sometimes Showing 404 not found page

Viewed 2627

I'm working on Laravel 8 and i have a problem sometimes when I refresh page or open it direct by link showing

Not found page 404 error , i tried lots of solutions on internet but no solution working with me .

Another note : it's also showing for me when i send request using ajax it's the most time showed for me .

My web.php :

<?php

use App\Http\Middleware\AdminAuth;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| 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!
|
*/

$adminPathName = env('ADMIN_PATH');

Route::get($adminPathName . '/test/{locale}', function ($locale) {
    session('lang', 'en');

    app()->setLocale($locale);
    echo App::getLocale();
});

Route::get('/', function () {
    return view('frontend.home');
});

$adminPathName = env('ADMIN_PATH');
$userPath = env('USER_PATH');

Route::get($adminPathName . '/login', 'Admin\LoginController@login');
Route::post($adminPathName . '/signin', 'Admin\LoginController@signin');
Route::group(['middleware' => ['AdminAuth']], function () {
    $adminPathName = env('ADMIN_PATH');
    Route::get($adminPathName . '/dashboard', 'Admin\AdminController@home');
    Route::get($adminPathName . '/languages/manage-languages', 'Admin\LanguageController@index');
    Route::post($adminPathName . '/languages/add-language', 'Admin\LanguageController@addLanguage');
    Route::post($adminPathName . '/languages/add-translate', 'Admin\LanguageController@addTranslate');
    Route::post($adminPathName . '/languages/update-translate', 'Admin\LanguageController@updateTranslate');
    Route::post($adminPathName . '/languages/remove-translate', 'Admin\LanguageController@removeTranslate');
    Route::post($adminPathName . '/languages/remove-language', 'Admin\LanguageController@removeLanguage');
    Route::post($adminPathName . '/languages/sync-language', 'Admin\LanguageController@syncLanguage');
    Route::get($adminPathName . '/languages/translate/{langId}', 'Admin\LanguageController@translateById');
});


// todo this route should be added below .
Route::get('/login/facebook/callback', 'User\LoginController@facebookCallback');

Route::group(['prefix' => '/{locale}', 'middleware' => \App\Http\Middleware\SetLocale::class, 'as' => 'locale'], function () {

    $userPath = env('USER_PATH');

    Route::get('/', function () {
        return view('frontend.home');
    });
    Route::get($userPath . '/login', 'User\LoginController@login');
    Route::post($userPath . '/signin', 'User\LoginController@signin');
    Route::get($userPath . '/create-account', 'User\UserController@createAccount');
    Route::post($userPath . '/complete-register', 'User\UserController@completeRegister');

    /* Facebook Login & Register  */

    Route::get($userPath . '/social/facebook/redirect', 'User\LoginController@facebookRedirect');
    /* ./ Facebook Login & Register  */

    /* Google Login & Register  */
    Route::get($userPath . '/social/google/redirect', 'User\LoginController@googleRedirect');
    Route::get($userPath . '/social/google/callback', 'User\LoginController@googleCallback');
    /* ./ Google Login & Register  */

    Route::get('/change-language/{lang}', 'User\WebSiteController@changeLanguage');

    Route::group(['middleware' => ['UserAuth']], function () {
        $userPath = env('USER_PATH');
        Route::get($userPath . '/dashboard', 'User\UserController@dashboard');
        Route::get($userPath . '/update-profile', 'User\UserController@userProfile');
        Route::get($userPath . '/website/create-website', 'User\WebSiteController@newWebsite');
        Route::post($userPath . '/card/upload-gallery', 'User\UserController@uploadGallery');
        Route::get($userPath . '/cards/new-card/{card_lang}', 'User\CardController@newCard');
        Route::get($userPath . '/cards/new-card/{card_lang}/{card_key}', 'User\CardController@newCard');
        Route::post($userPath . '/cards/get-card-gallery', 'User\CardController@getGalleryByCardId');
        Route::post($userPath . '/cards/update-card', 'User\CardController@updateCard');
        Route::post($userPath . '/cards/update-card-logo', 'User\CardController@updateCardLogo');

        Route::get($userPath . '/logout', function () {
            auth('UserAuth')->logout();
            return redirect(ulocale_path('/login'));
        });
    });


});


Route::group(['domain' => '{account}.localhost'], function () {
    Route::get('/{id}/card', 'User\CardController@shoBusinessCardById');
});

And .htaccess file

RewriteEngine On
<IfModule mod_rewrite.c>
 #Session timeout

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

   Options +FollowSymlinks
   RewriteEngine On

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

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 ^ index.php


</IfModule>

The most time it's error showing in the below route :

 Route::post($userPath . '/cards/get-card-gallery', 'User\CardController@getGalleryByCardId');

Controller Side getGalleryByCardId :

public function getGalleryByCardId(Request $request)
{
    $imgs = DB::table('card_docs')
        ->where('user_id', usession('user_id'))
        ->where('card_key', $request->card_key)->get();

    return $imgs;
}
2 Answers

From what you describe, I feel that env() calls in your route file can be the issue.

When Laravel is not able to read environment values from .env file due to time lag in loading or any other issue it doesn't give any error related to environment variables not available, but continues processing.

Since your route files uses env() to get values from .env non availability of those values change the url of your routes hence you may get 404 error.

like $userPath = env('USER_PATH') and $adminPath = env('ADMIN_PATH') will result in values for both $userPath and $adminPath being null if there's issue is loading environment variables but execution will continue.

So where ever in urls these variables are used those urls will change with null as value where ever the variables are used

You can check the error logs when you get 404: if they have any entries for database or encryption related errors - it most likely is due to DotEnv not able to read from .env on time

@Donkarnash actually i'm not a professional in Laravel how can put it in config file ? can you explain that for me ?

You can create a new file at config/custom.php name whatever you like instead of custom.php

return [
    'userPath' => env('USER_PATH'),
    
    'adminPath' => env('ADMIN_PATH'),
];

Then you can make changes in your route file to use these values with config() helper

Route::get(config('custom.adminPath') . '/login', 'Admin\LoginController@login');
Route::post(config('custom.adminPath') . '/signin', 'Admin\LoginController@signin');
Route::prefix(config('custom.adminPath'))
    ->middleware(['AdminAuth'])
    ->group(function () {
        Route::get('/dashboard', 'Admin\AdminController@home');
        Route::get('/languages/manage-languages', 'Admin\LanguageController@index');
        Route::post('/languages/add-language', 'Admin\LanguageController@addLanguage');
        Route::post('/languages/add-translate', 'Admin\LanguageController@addTranslate');
        Route::post('/languages/update-translate', 'Admin\LanguageController@updateTranslate');
        Route::post('/languages/remove-translate', 'Admin\LanguageController@removeTranslate');
        Route::post('/languages/remove-language', 'Admin\LanguageController@removeLanguage');
        Route::post('/languages/sync-language', 'Admin\LanguageController@syncLanguage');
        Route::get('/languages/translate/{langId}', 'Admin\LanguageController@translateById');
    });

// todo this route should be added below .
Route::get('/login/facebook/callback', 'User\LoginController@facebookCallback');

Route::prefix('/{locale}/' . config('custom.userPAth'))
    ->middleware([\App\Http\Middleware\SetLocale::class])
    ->as('locale')
    ->group(function () {
        Route::get('/', function () {
            return view('frontend.home');
        });
        Route::get('/login', 'User\LoginController@login');
        Route::post('/signin', 'User\LoginController@signin');
        Route::get('/create-account', 'User\UserController@createAccount');
        Route::post('/complete-register', 'User\UserController@completeRegister');
        /* Facebook Login & Register  */

        Route::get('/social/facebook/redirect', 'User\LoginController@facebookRedirect');
        /* ./ Facebook Login & Register  */

        /* Google Login & Register  */
        Route::get('/social/google/redirect', 'User\LoginController@googleRedirect');
        Route::get('/social/google/callback', 'User\LoginController@googleCallback');

        Route::get('/change-language/{lang}', 'User\WebSiteController@changeLanguage');
        Route::group(['middleware' => ['UserAuth']], function () {
            Route::get('/dashboard', 'User\UserController@dashboard');
            Route::get('/update-profile', 'User\UserController@userProfile');
            Route::get('/website/create-website', 'User\WebSiteController@newWebsite');
            Route::post('/card/upload-gallery', 'User\UserController@uploadGallery');
            Route::get('/cards/new-card/{card_lang}', 'User\CardController@newCard');
            Route::get('/cards/new-card/{card_lang}/{card_key}', 'User\CardController@newCard');
            Route::post('/cards/get-card-gallery', 'User\CardController@getGalleryByCardId');
            Route::post('/cards/update-card', 'User\CardController@updateCard');
            Route::post('/cards/update-card-logo', 'User\CardController@updateCardLogo');

            Route::get('/logout', function () {
                auth('UserAuth')->logout();

                return redirect(ulocale_path('/login'));
            });
        });
    });

Route::group(['domain' => '{account}.localhost'], function () {
    Route::get('/{id}/card', 'User\CardController@shoBusinessCardById');
});

By using values from config instead of env, you can get a benefit by config caching.

In production you can also mitigate the routing url related issue by caching routes - but for that you will need to convert the closure based routes to controller based routes.

If you get 404 and you are using mcamara/laravel-localization then you can delete the contents of bootstrap/cache (the files only). I tried that and got some other issues everytime the cache was cleared and could not figure out why. Turns out that if you use mcamara/laravel-localization to translate routes etc you can't use "php artisan optimize", because you have localized routes.

So you need to use

php artisan route:trans:cache
php artisan route:trans:clear

https://github.com/mcamara/laravel-localization/blob/master/CACHING.md

This took me many hours to find so leaving it here if anyone else fights the same issue.

Related