How to Create upload a file using jQuery AJAX in Laravel 8
Using AJAX you can upload a file to the server without reloading the page.
Require to send CSRF token with AJAX request to upload the file.
In this tutorial, I show how you can upload a file using jQuery AJAX and display preview in Laravel 8.
1. Controller
Create a PageController
controller.
php artisan make:controller PageController
Create 2 methods –
- index() – Load
index
view. - uploadFile() – This method is used to upload the file.
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. 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 8</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
5. Conclusion
Use the FormData object if you want to pass extra data while sending AJAX request 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.
You can view this tutorial to know file upload without jQuery AJAX.