How to upload a file using jQuery AJAX in Laravel 10

File uploads are a common requirement for many web applications in web development. Uploading files using the old-fashioned way takes time and causes the page to refresh, disrupting the user experience. jQuery AJAX makes it easy to upload files without having to refresh the page.

Require to send CSRF token with AJAX request to upload the file in Laravel.

In this tutorial, I show how you can upload a file using jQuery AJAX with Validation and display preview in Laravel 10.

How to upload a file using jQuery AJAX in Laravel


Contents

  1. Create Controller
  2. Route
  3. Create View
  4. Output
  5. Conclusion

1. Create Controller

  • Create a PageController controller.
php artisan make:controller PageController
  • Open app/Http/Controllers/PageController.php file.

Create 2 methods –

  • index() – Load index view.
  • uploadFile() – This method is used to upload the file using AJAX.

Create $data Array to store return response.

Define file validation. I set the max file size to 2 MB (2048 Kb). If the file is not validated then assign 0 to $data['success'] and validation response to $data['error'].

If the file is validated then assign file name to $filename and file extension to $extension variable. Assign upload location "files" to $location variable.

Execute $file->move($location,$filename); to store the file.

Assign 1 to $data['success'], 'Uploaded Successfully!' to $data['message'], file path to $data['filepath'], and file extension to $data['extension'].

If the file is not uploaded then assign 2 to $data['success'] and 'File not uploaded.' message to $data['message'].

Return $data Array in JSON format.

Completed Code

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class PageController extends Controller {

    public function index(){
         return view('index');
    }

    public function uploadFile(Request $request){

         $data = array();

         $validator = Validator::make($request->all(), [
              'file' => 'required|mimes:png,jpg,jpeg,csv,txt,pdf|max:2048'
         ]);

         if ($validator->fails()) {

              $data['success'] = 0;
              $data['error'] = $validator->errors()->first('file');// Error response

         }else{
              if($request->file('file')) {

                   $file = $request->file('file');
                   $filename = time().'_'.$file->getClientOriginalName();

                   // File extension
                   $extension = $file->getClientOriginalExtension();

                   // File upload location
                   $location = 'files';

                   // Upload file
                   $file->move($location,$filename);
             
                   // File path
                   $filepath = url('files/'.$filename);

                   // Response
                   $data['success'] = 1;
                   $data['message'] = 'Uploaded Successfully!';
                   $data['filepath'] = $filepath;
                   $data['extension'] = $extension;
              }else{
                   // Response
                   $data['success'] = 2;
                   $data['message'] = 'File not uploaded.'; 
              }
         }

         return response()->json($data);
    }

}

2. Route

  • Open routes/web.php file.
  • Define 2 routes –
    • / – Load index view.
    • /uploadFile – This use to upload a file using AJAX.

Completed Code

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PageController;

Route::get('/', [PageController::class, 'index']);
Route::post('/uploadFile', [PageController::class, 'uploadFile'])->name('uploadFile');

3. Create View

Create index.blade.php file in resources/views/.

Stored CSRF token in the <meta > tag.

Display file upload response message in <div id="responseMsg"> using jQuery.

Created <img > and <a > element in <div id="filepreview"> to display a file preview according to the file extension using jQuery.

Create a file element and a button. Display error in <div id="err_file"> if file not validated using jQuery.


Script

Read CSRF token from <meta > tag and assign to CSRF_TOKEN variable.

On the button click read the selected file and assign to files variable.

If file not selected then alert("Please select a file."); otherwise, pass the selected file using FormData object. Also, pass CSRF_TOKEN with FormData.

Send AJAX POST request to "{{route('uploadFile')}} where pass FormData Object as data.

On successful callback check upload status –

  • If response.success == 1 means file successfully uploaded. Display the response message and preview the file according to the file extension.
  • If response.success == 2 means file is not uploaded. Display the response message.
  • If response.success does not equal 1 or 2 means the file is not validated. Display the error message.

Completed Code

<!DOCTYPE html>
<html>
<head>
    <title>How to upload a file using jQuery AJAX in Laravel 10</title>

    <!-- Meta -->
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

    <style type="text/css">
    .displaynone{
         display: none;
    }
    </style>
</head>
<body>

    <div class="container">

         <div class="row">

              <div class="col-md-12 col-sm-12 col-xs-12">

                    <!-- Response message -->
                    <div class="alert displaynone" id="responseMsg"></div>

                    <!-- File preview --> 
                    <div id="filepreview" class="displaynone" > 
                         <img src="" class="displaynone" with="200px" height="200px"><br>

                         <a href="#" class="displaynone" >Click Here..</a>
                    </div>

                    <!-- Form -->
                    <div class="form-group">
                         <label class="control-label col-md-3 col-sm-3 col-xs-12" for="name">File    <span class="required">*</span></label>
                         <div class="col-md-6 col-sm-6 col-xs-12">

                               <input type='file' id="file" name='file' class="form-control">

                               <!-- Error -->
                               <div class='alert alert-danger mt-2 d-none text-danger' id="err_file"></div>

                         </div>
                    </div>

                    <div class="form-group">
                         <div class="col-md-6">
                               <input type="button" id="submit" value='Submit' class='btn btn-success'>
                         </div>
                    </div>
              </div>
         </div>
    </div>

    <!-- Script -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script type="text/javascript">
    var CSRF_TOKEN = document.querySelector('meta[name="csrf-token"]').getAttribute("content");

    $(document).ready(function(){

         $('#submit').click(function(){
   
               // Get the selected file
               var files = $('#file')[0].files;

               if(files.length > 0){
                     var fd = new FormData();

                     // Append data 
                     fd.append('file',files[0]);
                     fd.append('_token',CSRF_TOKEN);

                     // Hide alert 
                     $('#responseMsg').hide();

                     // AJAX request 
                     $.ajax({
                          url: "{{ route('uploadFile') }}",
                          method: 'post',
                          data: fd,
                          contentType: false,
                          processData: false,
                          dataType: 'json',
                          success: function(response){

                                // Hide error container
                                $('#err_file').removeClass('d-block');
                                $('#err_file').addClass('d-none');

                                if(response.success == 1){ // Uploaded successfully

                                      // Response message
                                      $('#responseMsg').removeClass("alert-danger");
                                      $('#responseMsg').addClass("alert-success");
                                      $('#responseMsg').html(response.message);
                                      $('#responseMsg').show();

                                      // File preview
                                      $('#filepreview').show();
                                      $('#filepreview img,#filepreview a').hide();
                                      if(response.extension == 'jpg' || response.extension == 'jpeg' || response.extension == 'png'){

                                            $('#filepreview img').attr('src',response.filepath);
                                            $('#filepreview img').show();
                                      }else{
                                            $('#filepreview a').attr('href',response.filepath).show();
                                            $('#filepreview a').show();
                                      }
                                }else if(response.success == 2){ // File not uploaded

                                      // Response message
                                      $('#responseMsg').removeClass("alert-success");
                                      $('#responseMsg').addClass("alert-danger");
                                      $('#responseMsg').html(response.message);
                                      $('#responseMsg').show();
                                }else{
                                      // Display Error
                                      $('#err_file').text(response.error);
                                      $('#err_file').removeClass('d-none');
                                      $('#err_file').addClass('d-block');
                                } 
                          },
                          error: function(response){
                                console.log("error : " + JSON.stringify(response) );
                          }
                     });
               }else{
                     alert("Please select a file.");
               }

         });
    });
    </script>

</body>
</html>

4. Output

View Output


5. Conclusion

You can quickly integrate file uploads into your web applications by following the instructions in this article. It helps you to enhance the usability and user experience of your web applications, I hope this article was helpful in demonstrating how to upload files using jQuery AJAX in Laravel.

If you want to pass extra data while sending AJAX request for file upload then attach it with FormData object e.g. – fd.append('filename',"file 1");. Here, fd is FormData object.

Make sure to check upload_max_filesize and post_max_size values in the php.ini file if you are allowing large files to upload.

If your project is on Laravel 9 or 8 then also you can use it.

You can view this tutorial to know file upload without jQuery AJAX.

If you found this tutorial helpful then don't forget to share.