We noticed you're using an ad blocker

Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Laravel ajax image upload system

world cup 2023

WorldCup 2023

Get update standing, score, poll

Get Now

Image upload system is one of the most important parts of application or website development. Ajax image upload system enhances your application user experience. In this post, I'll show you step by step process on how to Ajax image upload with validation and showing upload progress bar by Laravel framework. Following this post, you can do the exact same things from Laravel version 5 to the current Laravel version.


The goal is to upload image for user profile. Suppose we have application or website where we need to update or add an image for user profile. For that, we'll do it with jQuery Ajax request. So that the Image will upload without any page refresh.


  • Route Define
  • Make Blade View & Js Code
  • Make Controller & Logic
  • Conclusion


Route Define

First, define 2 routes in your routes file. One for returning a view with a file input field and the last one is for submitting post request to our controller to upload the image.

Route::get('user/profile', 'UserController@getProfile')->name('profile');
Route::post('user/profile', 'UserController@postProfileUpdate')->name('updateProfile');


Make Blade View & Js Code

Make a blade view inside resource directory with the name profile.blade.php

    <div class="container">
        <div class="row">
            <div class="col-md-6">
                <h3><i class="fa fa-image"></i> Ajax Image Upload</h3>

                <h4>User Profile</h4>
                <div style="display: flex;">
                        <img class="imgPreview img img-circle" 
                         width="80" src="https://via.placeholder.com/80">
                    <div style="margin-left: 15px; flex-grow: 1">
                        <p>Choose a file</p>
                        <input id="photo" type="file">
                        <input type="hidden" name="id" value="{{$user->id}}">
                        <div class="progress">
                            <div class="progress-bar" 
                                 role="progressbar" aria-valuemin="0"


                <table class="table table-condensed table-bordered">
                        <td width="100">Name</td>

        $(function () {
                headers: {'X-CSRF-Token': '{{csrf_token()}}'}

            var id = $('input[name="id"]').val();

            $('#photo').change(function () {
                var photo = $(this)[0].files[0];
                var formData = new FormData();
                formData.append('id', id);
                formData.append('photo', photo);

                    xhr: function () {
                        var xhr = new window.XMLHttpRequest();
                        xhr.upload.addEventListener("progress", function (evt) {
                            if (evt.lengthComputable) {
                                var percentComplete = evt.loaded / evt.total;
                                percentComplete = parseInt(percentComplete * 100);
                                $('.progress-bar').css('width', percentComplete + '%');
                                if (percentComplete === 100) {
                                    console.log('completed 100%')

                                    var imageUrl = window.URL.createObjectURL(photo)
                                    $('.imgPreview').attr('src', imageUrl);
                                    setTimeout(function () {
                                        $('.progress-bar').css('width', '0%');
                                    }, 2000)
                        }, false);
                        return xhr;
                    url: '{{route('updateProfile')}}',
                    type: 'POST',
                    data: formData,
                    processData: false,
                    contentType: false,
                    success: function (res) {


Make Controller & Logic

Now make a controller with the artisan command php artisan make:controller UserController

namespace App\Http\Controllers;

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

class UserController extends Controller
    public function getProfile()
        $user = User::find(1);
        return view('profile', compact('user'));

    public function postProfileUpdate(Request $request)
    	$validator = Validator::make($request->all(), [
                		'photo' => 'required|image|mimes:png,jpg,jpeg|max:200',

        if ($validator->fails()) {
            return response()
                    'success' => false,
                    'error' =>  $validation->errors()->first()

        $user = User::find($request->input('id'));

        if ($request->hasFile('photo')) {
            $photo = $request->file('photo');

            $fileName = $user->id . "." . $photo->getClientOriginalExtension();
            $request->file('photo')->move(public_path('user-photos'), $fileName);
            $user->update(['photo' => $fileName]);

        return ['success'=>true,'message'=>'Successfully updated'];

Here, with the getProfile method, we just return user profile data to our profile view. In the postProfileUpdate we validated user-selected photo with Laravel validator facade. According to our validation user can only able to upload an image file with png, jpg, jpeg extensions image maximum 200KB.



Hope this step by step post will help you to learn ajax upload image upload in Laravel framework. If you find this is helpful for you then share it with others.

Share on

Related Post - Latest Post

Laravel Barcode generation tutorial

What's new in Laravel 9

Make laravel site super fast by page-cache!

Laravel maintenance mode bypass by Secret Route!

Laravel database backup automatically - cPanel shared hosting, VPS

Laravel Datatables - Ajax, Column, Buttons, Customization