Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Random NotFoundHttpException with ajax requests #32303

Closed
Suiding opened this issue Apr 8, 2020 · 6 comments
Closed

Random NotFoundHttpException with ajax requests #32303

Suiding opened this issue Apr 8, 2020 · 6 comments

Comments

@Suiding
Copy link

Suiding commented Apr 8, 2020

  • Laravel Version: 6.18.3
  • PHP Version: 7.3.10
  • Database Driver & Version: mysql
  • Windows 10 running xampp with multiple vhosts set up for my projects.

Description:

Upon ajax requests you would get a NotFoundHttpException at random. This happens more when the routes are not being cached, and still exist in lesser amount when the routes are cached.

I initially found out about this while implementing serverside datatables. The package https://github.com/yajra/laravel-datatables has a known bug while running php artisan serve. So I tried to reproduce it with a clean jQuery ajax request to make sure its not just this package but in Laravel itself.

Already tried composer update, dump-autoload, clearing cache. None worked.

Steps To Reproduce:

web.php

Route::group(['domain' => ('manage.'.env('APP_TLD')),'as' => 'admin.', 'namespace' => 'Admin'], function (){

        Route::namespace('Auth')->group(function (){
            Route::get('/', 'LoginController@showLoginForm')->name('login');
            Route::post('/', 'LoginController@login');
            Route::post('logout', 'LoginController@logout')->name('logout');
        });

        Route::group(['middleware' => 'auth:admin'], function (){
            Route::get('dashboard', 'DashboardController@index')->name('dashboard');

            Route::group(['as' => 'subscriptions.', 'prefix' => 'subscriptions'], function (){
                Route::get('/', 'SubscriptionController@index')->name('index');
            });

            Route::group(['as' => 'profiles.', 'prefix' => 'profiles'], function (){
                Route::get('/', 'ProfileController@index')->name('index');
                Route::post('/data', 'ProfileController@datatable')->name('datatable');
                Route::post('/test', function (){
                    return 'test';
                })->name('test');
            });

        });
});

Route::domain(env('APP_TLD'))->group(function (){

    Route::get('/', 'HomeController@frontpage')->name('index');

    Route::group(['prefix' => 'profile', 'middleware' => 'canAccessProfile'], function (){
        Route::get('/{profile}', 'ProfileController@show')->name('profile.show');

        Route::post('/{profile}/post', 'ProfileController@storePost')->name('profile.post');

        Route::get('/{profile}/tanks', 'TankController@index')->name('profile.tanks');
        Route::get('/{profile}/tanks/{tank}', 'TankController@show')->name('tank.show');
        Route::get('/{profile}/tanks/{tank}/parameters', 'TankController@parameters')->name('tank.parameters');
        Route::get('/{profile}/tanks/{tank}/album', 'TankController@album')->name('tank.album');

        Route::group(['middleware' => ['auth', 'profileBelongsToUser']], function (){
            Route::get('/{profile}/edit', 'ProfileController@edit')->name('profile.edit');
        });
    });

    Route::group(['prefix' => 'post', 'middleware' => ['auth', 'canAccessPost']], function (){
        Route::post('/', 'PostController@create')->name('post.store');
        Route::get('/{id}', 'PostController@show')->name('post.show');
    });

    Route::post('/subscribe', 'SubscribeController@subscribePost')->name('subscribe.post');
    Route::get('/subscribe/{email}', 'SubscribeController@confirm')->name('subscribe.confirm');

    Route::get('login', [
        'as' => 'login',
        'uses' => 'Auth\LoginController@showLoginForm'
    ]);
    Route::post('login', [
        'as' => '',
        'uses' => 'Auth\LoginController@login'
    ]);
    Route::get('logout', [
        'as' => 'logout',
        'uses' => 'Auth\LoginController@logout'
    ]);

    // Password Reset Routes...
    Route::get('password/reset', [
        'as' => 'password.request',
        'uses' => 'Auth\ForgotPasswordController@showLinkRequestForm'
    ]);
    Route::post('password/email', [
        'as' => 'password.email',
        'uses' => 'Auth\ForgotPasswordController@sendResetLinkEmail'
    ]);
    Route::get('password/reset/{token}', [
        'as' => 'password.reset',
        'uses' => 'Auth\ResetPasswordController@showResetForm'
    ]);
    Route::post('password/reset', [
        'as' => 'password.update',
        'uses' => 'Auth\ResetPasswordController@reset'
    ]);

    // Registration Routes...
    Route::get('register', [
        'as' => 'register',
        'uses' => 'Auth\RegisterController@showRegistrationForm'
    ]);
    Route::post('register', [
        'as' => '',
        'uses' => 'Auth\RegisterController@register'
    ]);

    // Verification Routes...
    Route::get('email/verify', 'Auth\VerificationController@show')
        ->name('verification.notice');
    Route::get('email/verify/{id}', 'Auth\VerificationController@verify')->name('verification.verify');
    Route::get('email/resend', 'Auth\VerificationController@resend')
        ->name('verification.resend');

});

Admin/ProfileController.php

class ProfileController extends Controller
{
    public function index(){
        $total_profiles = Profile::count();
        $today_profiles = Profile::whereDate('created_at', Carbon::today())->count();
        $confirmed_profiles = Profile::whereHas('user', function ($query){
            $query->where('email_verified_at', '!=', null);
        })->count();
        $total_profiles_chart = Profile::whereDate('created_at', '>=', Carbon::now()->subDays(7))
            ->groupBy(DB::raw('DATE(created_at)'))
            ->orderBy('created_at', 'ASC')
            ->get(array(
                DB::raw('Date(created_at) as date'),
                DB::raw('COUNT(*) as "count"')
            ));

        $dates = collect();
        foreach (range(0, 6) AS $i){
            $date = Carbon::now()->subDays( $i )->format( 'Y-m-d' );
            $dates->put( $date, 0);
        }
        $total_profiles_chart = $dates->merge($total_profiles_chart->pluck('count', 'date'))->reverse()->values()->toArray();

        return view('admin.pages.profiles.index', [
            'total_profiles' => $total_profiles,
            'today_profiles' => $today_profiles,
            'confirmed_profiles' => $confirmed_profiles,
            'total_profiles_chart' => $total_profiles_chart,
        ]);
    }

    public function datatable(){
        return datatables()->eloquent(Profile::query())
            ->addColumn('action', function (Profile $profile){
                return "Block";
            })
            ->editColumn('public', function(Profile $profile){
                return $profile->public ? 'Public' : 'Private';
            })
            ->toJson();
    }
}

Scripts inside admin.pages.profiles.index.blade.php

<script type="text/javascript">
        var table;

        $(document).ready(function() {
            table = $('#profiles_table').DataTable( {
                processing: true,
                serverSide: true,
                ajax: {
                    url: '{{ route('admin.profiles.datatable') }}',
                    type: 'POST',
                    data: function (d) {
                        d._token = '{{ csrf_token() }}'
                    }
                },
                // "stateSave": true,

                sDom: 'ltip',
                order: [[0, "asc"]],

                columns: [
                    {data: 'created_at', name: 'created_at', searchable: true, orderable: true},
                    {data: 'name', name: 'profiles.name', searchable: true, orderable: true},
                    {data: 'public', name: 'profiles.public', searchable: true, orderable: true},
                    {data: 'action', name: 'action', searchable: false, orderable: false}
                ]
            } );

            table.columns().eq(0).each(function (index) {
                var column = table.column(index);
                $('select, input', column.footer()).on('change', function () {
                    if(column.search() !== $(this).val())
                    {
                        var val = $(this).val();
                        column.search(val).draw();
                    }
                });

            });

        } );

        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': '{{ csrf_token() }}'
            }

        });

        $.ajax({
            url: '{{ route('admin.profiles.test') }}',
            type: 'POST',
            data: function (d) {
                d._token = '{{ csrf_token() }}'
            }
        })

    </script>

Complete message on failure:

{
    "message": "",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException",
    "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\RouteCollection.php",
    "line": 179,
    "trace": [
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
            "line": 635,
            "function": "match",
            "class": "Illuminate\\Routing\\RouteCollection",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
            "line": 624,
            "function": "findRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
            "line": 613,
            "function": "dispatchToRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
            "line": 170,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
            "line": 130,
            "function": "Illuminate\\Foundation\\Http\\{closure}",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\barryvdh\\laravel-debugbar\\src\\Middleware\\InjectDebugbar.php",
            "line": 65,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
            "line": 171,
            "function": "handle",
            "class": "Barryvdh\\Debugbar\\Middleware\\InjectDebugbar",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
            "line": 171,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
            "line": 171,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php",
            "line": 27,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
            "line": 171,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode.php",
            "line": 63,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
            "line": 171,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\fideloper\\proxy\\src\\TrustProxies.php",
            "line": 57,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
            "line": 171,
            "function": "handle",
            "class": "Fideloper\\Proxy\\TrustProxies",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
            "line": 105,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
            "line": 145,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
            "line": 110,
            "function": "sendRequestThroughRouter",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "D:\\Suiding\\Documenten\\git\\suiding-private\\trackmytank.com\\public\\index.php",
            "line": 55,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        }
    ]
}

Going to the admin.profiles.index page loads the view as expected. Triggers the ajax requests. One request to populate the datatable. And one request for this testing purpose. Monitoring the Chrome network tab shows http status code 404 at random for these request with the error NotFoundHttpException in the response. Without caching the routes it fails 50% of the time. With caching routes it fails like 5% of the time. When I don't get the 404, everything goes through and I get the expected response populating the table. This goes for both ajax request.

@driesvints
Copy link
Member

Hi there,

Thanks for reporting but it looks like this is a question which can be asked on a support channel. Please only use this issue tracker for reporting bugs with the library itself. If you have a question on how to use functionality provided by this repo you can try one of the following channels:

However, this issue will not be locked and everyone is still free to discuss solutions to your problem!

Thanks.

@Suiding
Copy link
Author

Suiding commented Apr 9, 2020

Problem is solved.

I added the 'tld' => env('APP_TLD') to the config/app.php and called the config('app.tld') in the routes file. Everything seems to be working now without any problem.

I still wonder why calling the env() in the routes seemed to work fine for regular requests and only gives problems so randomly when handling ajax requests. If anyone knows, I would love to hear more about this part!

@Suiding
Copy link
Author

Suiding commented Apr 9, 2020

Well, the problem isn't solved 100%.

The problem still exists but its way less frequently. And now I get new errors like "No application encryption key has been specified" And "Access denied for user 'forge'@'localhost'" while my .env is fine and in place.

These errors got me searching again and I found these threads:
#24510
laravel/nova-issues#1294

@Muhammad-Sarfaraz
Copy link

Please help me with what are you using to serve your application Most probably you are using artisan serve?

@Suiding
Copy link
Author

Suiding commented Jul 23, 2021

During that time I was serving the application through apache (xampp for windows) set up with a virtualhost pointing to my application.

@catalin00
Copy link

Have you found a solution for this problem? I am having it too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants