Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

SunnyBoy's avatar

Laravel Ajax - Put request 500 internal server error

Hi All,

It has been almost a week and still I'm not able to find out the 500 internal server error mystery which is happening only on when the application is on running on a shared server (works perfectly on local machine).

Summary of what i am trying: After creating a Ticket, add n-number of TicketNotes to the Ticket while editing the Ticket. In order to add the TicketNotes I am using ajax CRUD for the TicketNotes. BTW I am using Bootstrap 3 Modal.

I am able to update Ticket but when I try to update TicketNotes it fails on shared hosting, throws this error in console.log. And the best part is GET POST and DELETE all are working only on PUT it's throwing error. Its so frustrating... NEED HELP!!!

Here is my code:

app.blade.php

. . .
. . .

<meta name="csrf-token" content="{{ csrf_token() }}">

. . .
. . .

Ticket View with editTicket.blade.php [TicketNotes - Table]

<div class="form-group">
    <label for="note_description">@lang('description-od-additional-request')</label>
    <button type="button" class="btn btn-default btn-embossed btn-sm pull-right" data-toggle="modal" data-target="#addNoteModal"><span class="fui-plus"></span>&nbsp; @lang('add-new')</button>
    <table class="table table-bordered table-striped table-hover">
        <thead>
            <tr>
                <th valign="middle">@lang('hash')</th>
                <th>@lang('note-description')</th>
                <th>@lang('add-deliverables')</th>
                <th>@lang('created')</th>
                <th>@lang('actions')</th>
            </tr>
        </thead>
        <tbody id="ticketNotesTable">
            @foreach($ticketNotes as $noteIndex => $ticketNote)
            <tr id="ticketNote{{$ticketNote->TicketNoteID}}">
                <td class="noteCol1">{{++$noteIndex}}</td>
                <td>{!! $ticketNote->NoteDescription !!}</td>
                <td>{!! $ticketNote->AddDeliverables !!}</td>
                <td>{{ $ticketNote->created_at->diffForHumans() }}</td>
                <td>
                <div class="btn-group" role="group" aria-label="Ticket Notes">
                    <button type="button" class="editNoteModal btn btn-link" data-noteid="{{$ticketNote->TicketNoteID}}"><i class="fui-new"></i></button>
                    <button type="button" class="deleteNoteModal btn btn-link" data-noteid="{{$ticketNote->TicketNoteID}}"><i class="fui-trash text-danger"></i></button>
                </div>
                </td>
            </tr>
            @endforeach
        </tbody>
    </table>
</div>

TicketNotes Modal View [tickets/ticketnotes/edit.blade.php]

<div class="modal fade" id="editNoteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">@lang('edit-additional-request')</h4>
            </div>
            <div class="modal-body">
                <form id="editNoteForm">
                    <input type="hidden" id="edit_ticketNote_id">
                    <div class="form-group">
                        <label for="edit_note_description">@lang('description-od-additional-request')</label>
                        <textarea class="form-control" id="edit_note_description"></textarea>
                    </div>
                    <div class="form-group">
                        <label for="edit_additional_deliverables">@lang('additional-deliverables')</label>
                        <textarea class="form-control" id="edit_additional_deliverables"></textarea>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">@lang('close')</button>
                <button type="button" class="btn btn-primary editNotes">@lang('update')</button>
            </div>
        </div>
    </div>
</div>

Ajax Script [edit method]

    // Ajax Setup
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

    // Edit a ticket note
    $(document).on('click', '.editNoteModal', function () {
        var noteId = $(this).data('noteid')
        $.ajax({
            type: "GET",
            url: '/ticketNotes/'+ noteId,
            success: function (data) {
                console.log(data);
                $('#edit_ticketNote_id').val(data.TicketNoteID);
                $('#edit_note_description').val(data.NoteDescription);
                $('#edit_additional_deliverables').val(data.AddDeliverables);
                $('#editNoteModal').modal('show');
            },
            error: function (data) {
                console.log('Error:', data);
            }
        });
    });
    $('#editNoteModal').on('click', '.editNotes', function () {
        var editNotesFormData = {
            edit_note_description: $('#edit_note_description').val(),
            edit_additional_deliverables: $('#edit_additional_deliverables').val()
        }
        $.ajax({
            type: 'PUT',
            url: '/ticketNotes/'+ $('#edit_ticketNote_id').val(),
            data: editNotesFormData,
            dataType: 'json',
            success: function (data) {
                console.log('Success:', data);
                var editTicketNote = '<tr id="ticketNote' + data.TicketNoteID + '">'
                    editTicketNote += '<td class="noteCol1"></td>'
                    editTicketNote += '<td>' + data.NoteDescription + '</td>'
                    editTicketNote += '<td>' + data.AddDeliverables + '</td>'
                    editTicketNote += '<td>Just now!</td>'
                    editTicketNote += '<td><button type="button" class="editNoteModal btn btn-link" data-noteid="' + data.TicketNoteID + '"><i class="fui-new"></i></button>'
                    editTicketNote += '<button type="button" class="deleteNoteModal btn btn-link" data-noteid="' + data.TicketNoteID + '"><i class="fui-trash text-danger"></button></td><tr>';

                toastr.success('Successfully updated Additional Request!', 'Success Alert', {timeOut: 3000});
                $('#ticketNote' + data.TicketNoteID).replaceWith(editTicketNote);
                $('.noteCol1').each(function (editIndexNotes) {
                    $(this).html(++editIndexNotes);
                });
                $('#editNoteForm').trigger('reset');
                $('#editNoteModal').modal('hide');
            },
            error: function (data) {
                console.log('Error:', data);
            }
        });
    });

Controller [update method]

public function update(Request $request, $id)
    {
        $ticketNote = TicketNote::findOrFail($id);
        $ticketNote->NoteDescription = $request->edit_note_description;
        $ticketNote->AddDeliverables = $request->edit_additional_deliverables;
        $ticketNote->save();
        return response()->json($ticketNote);
    }

THANKS!!!

0 likes
21 replies
Snapey's avatar

have you looked in the laravel log file?

SunnyBoy's avatar

@SNAPEY - That’s another story, I deleted the log file thinking that it will be created again but it’s not happening.

jlrdw's avatar

Try changing to post in ajax, but have a "put" route.

Talinon's avatar

If it works locally but not in your shared environment, it's possible your provider has configured the webserver to disallow some HTTP verbs.

If you're getting an HTTP 5xx error, and there is nothing within the Laravel log, then I would conclude it's being blocked at the server level and the request isn't even reaching Laravel.

As @jlrdw mentioned, try changing it to POST just to see if it goes thru.

You could also try sending something via Postman and see what response you get.

Cronix's avatar
Cronix
Best Answer
Level 67

If you try changing to post method, also add {_method: 'PUT'} to the data being sent.

What does the response tab look like in your browsers dev tools for your ajax request? Usually it shows the stack trace.

SunnyBoy's avatar

@JLRDW - I tried POST instead of PUT in ajax call and i get the following error:

{
    "message": "The POST method is not supported for this route. Supported methods: GET, HEAD, PUT, PATCH, DELETE."
}
jlrdw's avatar

Did you clear temp views, all cache, browser cache, etc. Give me a minute or so also.

SunnyBoy's avatar

@TALINON - But then how i am able to update the ticket normally with direct controller. I get error only via ajax that too only when i update. I can add and delete using ajax. Not sure how Postman works. ?

jlrdw's avatar

In an ajax demo I did, i am only doing 2 fields, just simple demo:

<script>
    $(function () {
        $("#postjq").click(function (event)
        {
            event.preventDefault();
            var $post = {};
            $post.petid = $('#petid').val();
            $post.species = $('#species').val();
            $post.ocheck = ($("#ocheck").prop("checked") == true ? '1' : '0');
            $post._token = document.getElementsByName("_token")[0].value
            $.ajax({
                url: 'petupdate',
                type: 'POST',
                data: $post,
                cache: false,
                success: function (data) {
                    alert('Your data updated');
                    return data;
                },
                error: function () {
                    alert('error handing here');
                }
            });
        });
    });

And I just used a simple route:

Route::put('petupdate', array('uses' => 'PetsController@petupdate'));

I know not real advanced, but that works.

Are you sure everything is loaded. Do an alert in the JS to ensure it's working.

But from what you said it is. I wonder if the token is getting through.

Edit, for put, post you don't need json, just normal put or post. Yes you can, but json is bigger for get request to return json back to an ajax response. If an API, then yes, json.

SunnyBoy's avatar

@CRONIX - As you mentioned i added the _method: 'PUT' to the ajax:data

// Edit Reference Entry
    $(document).on('click', '.editRefEntryModal', function () {
        var refId = $(this).data('refid');
        $.ajax({
            type: "GET",
            url: '/referenceEntries/'+ refId,
            success: function (data) {
                console.log(data);
                $('#edit_reference_id').val(data.ReferenceEntryID);
                $('#edit_notes').val(data.Notes);
                $('#editRefEntryModal').modal('show');
            },
            error: function (data) {
                console.log('Error:', data);
            }
        });
    });
    $('#editRefEntryModal').on('click', '.editRef', function () {
        var editNotesFormData = {
            edit_notes: $('#edit_notes').val(),
            _method: 'PUT' // as suggested by Cronix//
        }
        $.ajax({
            type: 'POST', // as suggested by jlrdw //
            url: '/referenceEntries/' + $('#edit_reference_id').val(),
            data: editNotesFormData,
            dataType: 'json',
            success: function (data) {
                console.log('Success:', data);
                var referenceEntryEdit = '<tr id="referenceEntry' + data.ReferenceEntryID + '">'
                    referenceEntryEdit += '<td class="refCol1"></td>'
                    referenceEntryEdit += '<td>' + data.Notes + '</td>'
                    referenceEntryEdit += '<td>Just now!</td>'
                    referenceEntryEdit += '<td><button type="button" class="editRefEntryModal btn btn-link" data-refid="' + data.ReferenceEntryID + '"><i class="fui-new"></i></button>'
                    referenceEntryEdit += '<button type="button" class="deleteRefEntryModal btn btn-link" data-refid="' + data.ReferenceEntryID + '"><i class="fui-trash text-danger"></button></td><tr>';

                toastr.success('Successfully updated Reference Entry!', 'Success Alert', {timeOut: 3000});
                $('#referenceEntry' + data.ReferenceEntryID).replaceWith(referenceEntryEdit);
                $('.refCol1').each(function (editIndexRef) {
                    $(this).html(++editIndexRef);
                });
                $('#editRefForm').trigger('reset');
                $('#editRefEntryModal').modal('hide');
            },
            error: function (data) {
                var errors = data.responseJSON;
                if ($.isEmptyObject(errors) == false) {
                    $.each(errors.errors, function (key, value) {
                        $('#' + key)
                            .closest('.form-group')
                            .addClass('has-error')
                            .append('<span class="help-block"><strong>' + value + '</strong></span>');
                    });
                }
                toastr.error( errors.message , "Error Alert", {timeOut: 3000});
            }
        });
        $('form').find('.help-block').remove();
        $('form').find('.form-group').removeClass('has-error');
    });

Now i get this error

POST http://example.com/referenceEntries/24 422 (Unprocessable Entity)
SunnyBoy's avatar

@JLRDW - I did getting this

POST http://example.com/referenceEntries/24 405 (Method Not Allowed)

But then i realized my route is a resources route will try again

jlrdw's avatar

See my edited answer, you don't need to post using json.

Cronix's avatar

You're getting closer. 422 is usually a form validation error. I don't see you doing form validation in here though

    public function update(Request $request, $id)
    {
        $ticketNote = TicketNote::findOrFail($id);
        $ticketNote->NoteDescription = $request->edit_note_description;
        $ticketNote->AddDeliverables = $request->edit_additional_deliverables;
        $ticketNote->save();
        return response()->json($ticketNote);
    }

In you're ajax data, you're only sending

var editNotesFormData = {
    edit_notes: $('#edit_notes').val(),
    _method: 'PUT' // as suggested by Cronix//
}

You send an edit_notes field, but that update() method is expecting an edit_note_description field as well as edit_additional_deliverables. You aren't sending either.

Is that the correct update method?

Talinon's avatar

@sunnyboy You would get around it by method spoofing, just like HTML forms. That is what the _method field does.

I'm not suggesting this is your problem, just something to test to rule out with trial & error.

SunnyBoy's avatar

@JLRDW - Route

// Route::resource('referenceEntries', 'ReferenceEntriesController');
Route::post('referenceEntries', 'ReferenceEntriesController@store');
Route::get('referenceEntries', 'ReferenceEntriesController@index');
Route::get('referenceEntries/create', 'ReferenceEntriesController@create');
Route::get('referenceEntries/{referenceEntry}', 'ReferenceEntriesController@show');
Route::delete('referenceEntries/{referenceEntry}', 'ReferenceEntriesController@destroy');
Route::put('referenceEntries/{referenceEntry}', 'ReferenceEntriesController@update');
Route::get('referenceEntries/{referenceEntry}/edit', 'ReferenceEntriesController@edit');

Ajax Script

    $('#editRefEntryModal').on('click', '.editRef', function () {
        var editNotesFormData = {};
        editNotesFormData.edit_notes = $('#edit_notes').val();
        editNotesFormData._token = document.getElementsByName("csrf-token")[0].value
        $.ajax({
            type: 'POST',
            url: '/referenceEntries/' + $('#edit_reference_id').val(),
            data: editNotesFormData,
            // dataType: 'json',
            cache: false,
            success: function (data) {
                console.log('Success:', data);
                var referenceEntryEdit = '<tr id="referenceEntry' + data.ReferenceEntryID + '">'
                    referenceEntryEdit += '<td class="refCol1"></td>'
                    referenceEntryEdit += '<td>' + data.Notes + '</td>'
                    referenceEntryEdit += '<td>Just now!</td>'
                    referenceEntryEdit += '<td><button type="button" class="editRefEntryModal btn btn-link" data-refid="' + data.ReferenceEntryID + '"><i class="fui-new"></i></button>'
                    referenceEntryEdit += '<button type="button" class="deleteRefEntryModal btn btn-link" data-refid="' + data.ReferenceEntryID + '"><i class="fui-trash text-danger"></button></td><tr>';

                toastr.success('Successfully updated Reference Entry!', 'Success Alert', {timeOut: 3000});
                $('#referenceEntry' + data.ReferenceEntryID).replaceWith(referenceEntryEdit);
                $('.refCol1').each(function (editIndexRef) {
                    $(this).html(++editIndexRef);
                });
                $('#editRefForm').trigger('reset');
                $('#editRefEntryModal').modal('hide');
            },
            error: function (data) {
                var errors = data.responseJSON;
                if ($.isEmptyObject(errors) == false) {
                    $.each(errors.errors, function (key, value) {
                        $('#' + key)
                            .closest('.form-group')
                            .addClass('has-error')
                            .append('<span class="help-block"><strong>' + value + '</strong></span>');
                    });
                }
                toastr.error( errors.message , "Error Alert", {timeOut: 3000});
            }
        });

I get this POST 405 ERROR

{
    "message": "The POST method is not supported for this route. Supported methods: GET, HEAD, PUT, DELETE."
}

Wondering if this is correct?

editNotesFormData._token = document.getElementsByName("csrf-token")[0].value

as i am using

<meta name="csrf-token" content="{{ csrf_token() }}">
...
 $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
....

SunnyBoy's avatar

@CRONIX - My bad... actually i got 2 tables so was focusing on one first... lol

public function update(Request $request, $id)
    {
        $this->validate($request, [
            'add_refnotes' => 'required|string|max:255'
        ]);
        $referenceEntry = ReferenceEntry::findOrFail($id);
        $referenceEntry->Notes = $request->edit_notes;
        $referenceEntry->save();
        return response()->json($referenceEntry);
    }
SunnyBoy's avatar

@TALINON - I tried that as suggest by @cronix

$('#editRefEntryModal').on('click', '.editRef', function () {
        var editNotesFormData = {};
        editNotesFormData.edit_notes = $('#edit_notes').val();
        editNotesFormData._token = document.getElementsByName("csrf-token")[0].value
        editNotesFormData._method = 'PUT' 
        $.ajax({
            type: 'POST',
            url: '/referenceEntries/' + $('#edit_reference_id').val(),
            data: editNotesFormData,
            // dataType: 'json',
            cache: false,
            success: function (data) {
                console.log('Success:', data);
                var referenceEntryEdit = '<tr id="referenceEntry' + data.ReferenceEntryID + '">'
                    referenceEntryEdit += '<td class="refCol1"></td>'
                    referenceEntryEdit += '<td>' + data.Notes + '</td>'
                    referenceEntryEdit += '<td>Just now!</td>'
                    referenceEntryEdit += '<td><button type="button" class="editRefEntryModal btn btn-link" data-refid="' + data.ReferenceEntryID + '"><i class="fui-new"></i></button>'
                    referenceEntryEdit += '<button type="button" class="deleteRefEntryModal btn btn-link" data-refid="' + data.ReferenceEntryID + '"><i class="fui-trash text-danger"></button></td><tr>';

                toastr.success('Successfully updated Reference Entry!', 'Success Alert', {timeOut: 3000});
                $('#referenceEntry' + data.ReferenceEntryID).replaceWith(referenceEntryEdit);
                $('.refCol1').each(function (editIndexRef) {
                    $(this).html(++editIndexRef);
                });
                $('#editRefForm').trigger('reset');
                $('#editRefEntryModal').modal('hide');
            },
            error: function (data) {
                var errors = data.responseJSON;
                if ($.isEmptyObject(errors) == false) {
                    $.each(errors.errors, function (key, value) {
                        $('#' + key)
                            .closest('.form-group')
                            .addClass('has-error')
                            .append('<span class="help-block"><strong>' + value + '</strong></span>');
                    });
                }
                toastr.error( errors.message , "Error Alert", {timeOut: 3000});
            }
        });

getting this error

 http://example.com/referenceEntries/24 422 (Unprocessable Entity)
Cronix's avatar

Ok, well it's the same issue.

The controller is expecting

$this->validate($request, [
            'add_refnotes' => 'required|string|max:255' // change add_refnotes to edit_notes
        ]);

Your ajax isn't sending that field add_refnotes. It's sending edit_notes,

var editNotesFormData = {
    edit_notes: $('#edit_notes').val(),
    _method: 'PUT'
}

so validation is failing and you're getting the correct 422 error back for that.

SunnyBoy's avatar

@CRONIX - That was embarrassing... Thanks for pointing out that... YOU ROCK!!!

@jlrdw : You are Awesome man!!! it works after change PUT to POST in ajax. Cool part is I still don't have to change the route so it worked with resource route.

THANKS A TON GUYS!!!

jlrdw's avatar

Glad you got it.

I may save a link to this post to help folks in future who have similar question. Easier than going over it again.

Yours is a more advanced example.

SunnyBoy's avatar

@JLRDW - We are lucky to have guys like you around this amazing community! Thanks a bunch

Here is how my final piece of code looks like:

// Edit Reference Entry
    $(document).on('click', '.editRefEntryModal', function () {
        var refId = $(this).data('refid');
        $.ajax({
            type: "GET",
            url: '/referenceEntries/'+ refId,
            success: function (data) {
                console.log(data);
                $('#edit_reference_id').val(data.ReferenceEntryID);
                $('#edit_notes').val(data.Notes);
                $('#editRefEntryModal').modal('show');
            },
            error: function (data) {
                console.log('Error:', data);
            }
        });
    });
    $('#editRefEntryModal').on('click', '.editRef', function () {
        var editNotesFormData = {
            edit_notes: $('#edit_notes').val(),
            _method: 'PUT' // as suggested by @cronix 
        };
        $.ajax({
            type: 'POST', // as suggested by @jlrdw 
            url: '/referenceEntries/' + $('#edit_reference_id').val(),
            data: editNotesFormData,
            dataType: 'json',
            cache: false,
            success: function (data) {
                console.log('Success:', data);
                var referenceEntryEdit = '<tr id="referenceEntry' + data.ReferenceEntryID + '">'
                    referenceEntryEdit += '<td class="refCol1"></td>'
                    referenceEntryEdit += '<td>' + data.Notes + '</td>'
                    referenceEntryEdit += '<td>Just now!</td>'
                    referenceEntryEdit += '<td><button type="button" class="editRefEntryModal btn btn-link" data-refid="' + data.ReferenceEntryID + '"><i class="fui-new"></i></button>'
                    referenceEntryEdit += '<button type="button" class="deleteRefEntryModal btn btn-link" data-refid="' + data.ReferenceEntryID + '"><i class="fui-trash text-danger"></button></td><tr>';

                toastr.success('Successfully updated Reference Entry!', 'Success Alert', {timeOut: 3000});
                $('#referenceEntry' + data.ReferenceEntryID).replaceWith(referenceEntryEdit);
                $('.refCol1').each(function (editIndexRef) {
                    $(this).html(++editIndexRef);
                });
                $('#editRefForm').trigger('reset');
                $('#editRefEntryModal').modal('hide');
            },
            error: function (data) {
                var errors = data.responseJSON;
                if ($.isEmptyObject(errors) == false) {
                    $.each(errors.errors, function (key, value) {
                        $('#' + key)
                            .closest('.form-group')
                            .addClass('has-error')
                            .append('<span class="help-block"><strong>' + value + '</strong></span>');
                    });
                }
                toastr.error( errors.message , "Error Alert", {timeOut: 3000});
            }
        });
        $('form').find('.help-block').remove();
        $('form').find('.form-group').removeClass('has-error');
    });
1 like

Please or to participate in this conversation.