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

tomasosho's avatar

Can someone help me out

I am trying to upload, crop then save my image to my database. The problem i have is the upload button is not wotking. and when i get it to work, it doesn't send data to the controller.

<html>  
    <head>  
        <title>Test Test</title>  
  
    <script src="{{asset('js/jquery.min.js')}}"></script>  
		<script src="{{asset('js/bootstrap.min.js')}}"></script>
		<script src="{{asset('js/croppie.js')}}"></script>
		<link rel="stylesheet" href="{{asset('css/bootstrap.min.css')}}" />
		<link rel="stylesheet" href="{{asset('css/croppie.css')}}" />
    </head>  
    <body>  
        <div class="container">
          <br />
      <h3 align="center">Image Crop & Upload using JQuery with PHP Ajax</h3>
      <br />
      <br />
   <div class="panel panel-default">
      <div class="panel-heading">Select Profile Image</div>
      <div class="panel-body" align="center">
       <input type="file" name="upload_image" id="upload_image" accept="image/*" />
       <br />
       <div id="uploaded_image"></div>
      </div>
     </div>
    </div>
    </body>  
</html>

<div id="uploadimageModal" class="modal" role="dialog">
 <div class="modal-dialog">
  <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">&times;</button>
          <h4 class="modal-title">Upload & Crop Image</h4>
        </div>
        <div class="modal-body">
          <div class="row">
       <div class="col-md-8 text-center">
        <div id="image_demo" style="width:350px; margin-top:30px"></div>
       </div>
       <div class="col-md-4" style="padding-top:30px;">
        <br />
        <br />
        <br/>
        <button class="btn btn-success crop_image">Crop & Upload Image</button>
     </div>
    </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>
     </div>
    </div>
</div>

<script>  
$(document).ready(function(){

 $image_crop = $('#image_demo').croppie({
    enableExif: true,
    viewport: {
      width:200,
      height:200,
      type:'square' //circle
    },
    boundary:{
      width:300,
      height:300
    }
  });

  $('#upload_image').on('change', function(){
    var reader = new FileReader();
    reader.onload = function (event) {
      $image_crop.croppie('bind', {
        url: event.target.result
      }).then(function(){
        console.log('jQuery bind complete');
      });
    }
    reader.readAsDataURL(this.files[0]);
    $('#uploadimageModal').modal('show');
  });

  $('.crop_image').click(function(event){
    $image_crop.croppie('result', {
      type: 'canvas',
      size: 'viewport'
    }).then(function(response){
      $.ajax({
        url:"/profile",
        type: "POST",
        data:{"image": response},
        success:function(data)
        {
          $('#uploadimageModal').modal('hide');
          $('#uploaded_image').html(data);
        }
      });
    })
  });

});  
</script>
0 likes
27 replies
tomasosho's avatar

In my console when the Upload button is not working i get 405 Method Not Allowed

guybrush_threepwood's avatar

What errors are you getting? You seem to be missing the CSRF token (unless you're setting it up someplace else):

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

This in turn requires that you set the following tag in your HTML head section:

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

It would be nice to have a look at the route and controller files too.

tomasosho's avatar

i'm getting

jquery.min.js:4 POST http://127.0.0.1:8000/profile 405 (Method Not Allowed)
guybrush_threepwood's avatar

Have you added the CSRF token to the Ajax request? Is the profile route configured to accept a POST request?

tomasosho's avatar

Yes CRSF token is set

Route::post('/profile', 'ProfilePsController@update_avatar')->middleware('auth');
guybrush_threepwood's avatar

Try adding it the simple way:

      $.ajax({
        url:"/profile",
        type: "POST",
        headers: { "X-CSRF-TOKEN": "{{ csrf_token() }}" },
        data:{"image": response},
        success:function(data)
        {
          $('#uploadimageModal').modal('hide');
          $('#uploaded_image').html(data);
        }
      });
tomasosho's avatar

I'm getting this now

POST http://127.0.0.1:8000/profile 422 (Unprocessable Entity)
guybrush_threepwood's avatar

That means it's failing validation. You can check out the response with Chrome DevTools to see a detailed error:

Open DevTools (CTRL+Shift+I on PC), go to the Network tab, filter by XHR and click over the item that says "profile" (you might need to upload the file again for the message to appear). You'll get the detailed error message in JSON format.

Can I see the Controller code?

tomasosho's avatar

My Controller

$request->validate([
            'avatar' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        ]);

        $user = Auth::user();

        $avatarName = $user->id.'_avatar'.time().'.'.request()->avatar->getClientOriginalExtension();

        $request->avatar->storeAs('avatars',$avatarName);

        $user->avatar = $avatarName;
        $user->save();

        return redirect("/profile/{$user->id}/{$user->username}")
            ->with('success','You have successfully upload image.');

When i filtered the error message to XHR i got {message: "The given data was invalid.", errors: {avatar: ["The avatar field is required."]}} errors: {avatar: ["The avatar field is required."]} avatar: ["The avatar field is required."] message: "The given data was invalid."

tomasosho's avatar

I changed the input name to avatar and i'm still getting same error

guybrush_threepwood's avatar

There's no need to change the input name, you should update the AJAX call:

      $.ajax({
        url:"/profile",
        type: "POST",
        headers: { "X-CSRF-TOKEN": "{{ csrf_token() }}" },
        data:{"avatar": response},
        success:function(data)
        {
          $('#uploadimageModal').modal('hide');
          $('#uploaded_image').html(data);
        }
      });

You can do return $request->all(); in your controller (before validation) to check with DevTools exactly what you're sending.

tomasosho's avatar

Got this error message

{message: "The given data was invalid.",…}
errors: {upload_image: ["The upload image field is required."]}
upload_image: ["The upload image field is required."]
0: "The upload image field is required."
message: "The given data was invalid."

when i took out the validation, i got an error 500

guybrush_threepwood's avatar

Please check that the field name that you're attempting to validate ("avatar"):

$request->validate([
    'avatar' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);

Is the same as key sent in the data object of the ajax call:

$.ajax({
        url:"/profile",
        type: "POST",
        headers: { "X-CSRF-TOKEN": "{{ csrf_token() }}" },
        data:{"avatar": response},
        success:function(data)
        {
          $('#uploadimageModal').modal('hide');
          $('#uploaded_image').html(data);
        }
      });

If you return early in your controller you should be able to see exactly what's being sent in the request:

        // Check the request
	return $request->all();

        $request->validate([
            'avatar' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        ]);

        $user = Auth::user();

        $avatarName = $user->id.'_avatar'.time().'.'.request()->avatar->getClientOriginalExtension();

        $request->avatar->storeAs('avatars',$avatarName);

        $user->avatar = $avatarName;
        $user->save();

        return redirect("/profile/{$user->id}/{$user->username}")
            ->with('success','You have successfully upload image.');
1 like
tomasosho's avatar

Thanks, it's working but the cropped image is not saving or updating. or it's not submitting the image in the controller

1 like
guybrush_threepwood's avatar

Does that mean that the full-size picture is being saved? Or nothing is being saved at all?

guybrush_threepwood's avatar

Did you remove this line?

return $request->all();

It's only meant as a temporary change to troubleshoot your code.

1 like
tomasosho's avatar

I think i'd have to convert from URI to save as image. Can you help?

kkhicher1's avatar

first (in your controller method)

dd($request->avatar)  

if you get big string value then you need to decode your base64 image with php base64_decode function

base64_decode ( string $data [, bool $strict = false ] ); 

its a php function you can use in your controller...

Hope its help

1 like
tomasosho's avatar

Last one

I want to save the pictures in a folder called avatars

My present code, saves it directly to the public folder

if(isset($_POST["avatar"]))
        {
        $data = $_POST["avatar"];

        $image_array_1 = explode(";", $data);

        $image_array_2 = explode(",", $image_array_1[1]);

        $data = base64_decode($image_array_2[1]);

        $imageName = time() . '.png';

        file_put_contents($imageName, $data);

        $user = Auth::user();

        $user->avatar = $imageName;
        $user->save();

        return redirect("/profile/{$user->id}/{$user->username}")
            ->with('success','You have successfully upload image.');
        }
tomasosho's avatar

This is telling me filepath does not exist

file_put_contents('storage/public/avatars',file_get_contents($imageName, $data));
Tray2's avatar

I suggest you check this link

https://stackoverflow.com/questions/44283986/how-to-upload-an-image-through-jquery

     <html>
        <head>
            <meta charset="UTF-8">
            <title>AJAX image upload with, jQuery</title>
            <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
            <script type="text/javascript">
                $(document).ready(function (e) {
                    $('#upload').on('click', function () {
                        var file_data = $('#file').prop('files')[0];
                        var form_data = new FormData();
                        form_data.append('file', file_data);
                        $.ajax({
                            url: 'http://localhost/ci/index.php/welcome/upload', // point to server-side controller method
                            dataType: 'text', // what to expect back from the server
                            cache: false,
                            contentType: false,
                            processData: false,
                            data: form_data,
                            type: 'post',
                            success: function (response) {
                                $('#msg').html(response); // display success response from the server
                            },
                            error: function (response) {
                                $('#msg').html(response); // display error response from the server
                            }
                        });
                    });
                });
            </script>
        </head>
        <body>
            <p id="msg"></p>

            <input type="file" id="file" name="file" multiple />
            <button id="upload">Upload</button>
        </body>
    </html>
´´´
tomasosho's avatar

I've done that @guybrush_threepwood and @kkhicher1 were really helpful. I just need to correct my file path

This is telling me filepath does not exist

file_put_contents('storage/public/avatars',file_get_contents($imageName, $data));
guybrush_threepwood's avatar
Level 33

Have you tried using the Storage facade instead?

$fileName = 'public/avatars/' . $imageName;
Storage::disk('local')->put($fileName, $data);

That will put the file in the storage/app/public/avatars folder.

Remember to reference the facade at the top of your controller like this: use Illuminate\Support\Facades\Storage;

Good luck

1 like
guybrush_threepwood's avatar

In order to show the image later you have to create a symbolic link to your storage folder by running: php artisan storage:link.

Then you can access the file like this:

<img src="{{ asset('storage/avatars/avatar.png') }}">
1 like
guybrush_threepwood's avatar

If you insist in uploading the file directly to the public folder (I wouldn't recommend it), this is the correct syntax:

$fileName = 'avatars/' . $imageName;
file_put_contents($fileName, $data);
kkhicher1's avatar

@tomasosho => as per @guybrush_threepwood it's very simple process to store file into your storage folder or public folder.... 1st you have to decide where you want to store then implement the code...

Please or to participate in this conversation.