alex32's avatar

Laravel 10 | Why ajax [POST] throw an error with route [POST]?

I've seen the post below, but I'm still unsure why the POST method doesn't work. I could probably use GET but .. am I using POST the wrong way? (the same code worked fine in Joomla) I removed the data on the URL (test + data), but Laravel return the same 405 . Many thanks.

Laracast: https://laracasts.com/index.php/index.php/discuss/channels/laravel/the-get-method-is-not-supported-for-this-route-supported-methods-post

POST ERR: http://localhost/jxfileupload?task=file_upload&mp3Len=89&pid=1&app=stt 405 (Method Not Allowed)

AJAX :

var task = "?task=file_upload"; proid= proid?proid:1;
var data = "&mp3Len="+mp3Len+"&pid="+proid+"&app="+app;  
var link = pagedata.app_url+"/jxfileupload/"+task+data;   // localhost/jxfileupload +task+data

var file_data = $('#select_file').prop('files')[0];   
var fdata = new FormData();                  
fdata.append('file', file_data);    

$.ajax({
    xhr: function() {
      var xhr = new window.XMLHttpRequest();

      xhr.upload.addEventListener("progress", function(evt) {
        if (evt.lengthComputable) {
          var percent = evt.loaded / evt.total;
          percent  = parseInt(percent * 100);
          if (percent < 90) { $("#upload_prog").width(percent+"%").html(''); } // allow full upload
          
          if (percent === 100) {
            $("#upload_file").html("Uploaded").prop('disabled', true); 
              
          }

        }
      }, false);

      return xhr;
    },
    url: link,
    type: "POST",
    data: (fdata),
    processData: false,
    contentType: false,     
    cache: false 
    // ...
  
 });   

AjaxController:

class AjaxController extends Controller
{
    public function file_upload()  {     
			// ...
	}

//...
}        

Route

Route::controller(AjaxController::class)->group(function () {
    Route::get('/jxuserfiles', 'get_userFiles');
    Route::post('/jxfileupload', 'file_upload');
});
0 likes
8 replies
jlrdw's avatar

Do you have enctype for form, do you have the CSRF token field.

alex32's avatar

The upload button is not inside a <form tag. I'm not using a @csrf token for testing.

<div class="input_container"> 
  <input   id="select_file" type="file"/>  
  <button class="btn btn-primary " id="upload_file" style="min-width: fit-content; float: right;height: 45px;" disabled>Upload</button>&nbsp; 
</div>   
Snapey's avatar

depends what other routes you have also

alex32's avatar

Here are the other routes installed by jetstream:

Route::middleware([
    'auth:sanctum',
    config('jetstream.auth_session'),
    'verified',
])->group(function () {
    Route::get('/dashboard', function () {
        return view('dashboard');
    })->name('dashboard');
});

And if I change POST to GET, (Route + ajax) I get 500 server error:

Route::get('/jxfileupload', "App\Http\Controllers\AjaxController@file_upload");

public function file_upload()  {     
    
    $uid = Auth::id()?:1;  // 1 for testing if not logged

    // test
    ddd($uid);
    return 
}

Console:

http://localhost/jxfileupload?task=file_upload&mp3Len=89&pid=1&app=stt&_=1699782230059 500 (Internal Server Error)

Since Ajax works fine for a normal HTTP request (sending variables to the same method), I suspect this XHR request could be handled differently by Route? Thanks

alex32's avatar

Thanks, I fixed the typo. But the function file_upload() still doesn't get called. When I click "Upload" nothing happen - no errors- ddd($uid) doesn't print anything.

Snapey's avatar

@alex32 check network tab in browser dev tools

Is request sent?

What URL?

What response?

and CSRF, its not optional unless you exclude the route in the verifycsrf middleware

alex32's avatar

OK, I put the html inside a <form tag, back to POST with the same AJAX code, and it works. Thanks everyone.

Please or to participate in this conversation.