george1's avatar

Laravel Symfony\Component\HttpKernel\Exception\HttpException when uploading multiple image files with AJAX

I'm making a web app to which I would like from the user to be able to post multiple images to my server via AJAX. firstly, I want to check whether the files the user uploaded are legit (png, jpeg) and not something else. Laravel throws an

Symfony\Component\HttpKernel\Exception\HttpException error without message making it very hard for me to debug.

Also, I am getting an 419 error as soon as I select the images.

Anyone having an idea what it might be?

I made sure to include the csrf tokens on both form and JS. I am using jQuery for AJAX.

This is the snippet of my form:

<form action="{{ route('forum.thread.store', array($data['category']->path, $data['topic']->path)) }}" method="POST" enctype="multipart/form-data" >
    @csrf
    <div class="row">
        {{-- <div class="form-group"> --}}
            <label for="title">What's in your mind (title)?</label>
            <input type="text" class="form-control" name="title" id="title" value="{{ old('title') }}">
        {{-- </div> --}}
    </div>
    <div class="row">
        {{-- <div class="form-group"> --}}
            <label for="content">What would you like to discuss or ask (message)?</label>
            <textarea class="form-control" name="content" id="content" rows="6">{{ old('content') }}</textarea>
        {{-- </div> --}}
    </div>
    <div class="row">
        <div class="custom-control custom-checkbox mr-sm-2">
            <input type="checkbox" class="custom-control-input" id="question" name="question">
            <label class="custom-control-label" for="question">Question</label>
        </div>
    </div>

    <input accept=".gif,.jpeg,.jpg,.png" type="file" multiple="" class="" aria-label="Attach files to your post" id="images_upload">
    <input type="hidden" name="category" value="{{ $data['category']->path }}">
    <input type="hidden" name="topic" value="{{ $data['topic']->path }}">

    <button type="submit">Submit</button>
</form>

This is the snippet of the JS code:

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

var ImagesInput = document.getElementById("images_upload");
ImagesInput.addEventListener('change', handleImages, false);

function handleImages(e){

    var fd = new FormData();
    fd.append("images_upload", ImagesInput.files[0]);

    var ins = document.getElementById('images_upload').files.length;
    for (var x = 0; x < ins; x++) {
        fd.append("images_upload[]", ImagesInput.files[x]);
    }

    check_images(fd);

}

function check_images(images){
    $.ajax({

        type:'POST',
        url:'/forum_post_check_images',
        data: {images_upload: images, _token : $('meta[name="csrf-token"]').attr('content')},
        dataType: "JSON",
        contentType: false,
        cache: false,
        processData: false,
        success: function(data){

          document.getElementById("test-debug").innerHTML = data;

          if (JSON.parse(data).message == "success"){
              console.log("motherfucking works")
          }
      },
      error: function(data){

          // Something went wrong
          // HERE you can handle asynchronously the response 

          // Log in the console
          var errors = data.responseJSON;
          console.log(errors);
          console.log("motherfucking error")

          // or, what you are trying to achieve
          // render the response via js, pushing the error in your 
          // blade page
            errorsHtml = '<div class="alert alert-danger"><ul>';

            $.each( errors.error, function( key, value ) {
                errorsHtml += '<li>'+ value[0] + '</li>'; //showing only the first error.
            });
            errorsHtml += '</ul></div>';

            $( '#form-errors' ).html( errorsHtml ); //appending to a <div id="form-errors"></div> inside form  
        }
      });
}  

The route is defined as:

Route::post('/forum_post_check_images', ['uses' => 'forumThreadController@check_legit_image', 'as' => 'forum.thread.images_check']);
And the Controller function which is meant to be called after the AJAX execution:

    public function check_legit_image(Request $request){
        dd($request);
    }

The end goal is to see the output of:

dd($request) Just for me to see that the request is working and the images are sent to the server (controller) to be processed.

I have an idea that the issue may be that PHP doesn't let me to upload files more than 2MB, but I cannot be absolutely sure.

0 likes
11 replies
jlrdw's avatar

Have you tried increasing upload_max_filesize. Also use your dev tools to see what's going on.

george1's avatar

How could I increase it? I have been looking around at that couple of weeks ago for days and I had no luck. I am using php artisan serve. Which dev tools you mean?

jlrdw's avatar

The dev tools built into modern browsers, start with troubleshooting there. You can see the request, response, etc. I use chrome dev tools.

george1's avatar

I see Headers, Preview, Response, Cookies, Timing. Which of those information is relevant? I still see error 419 as soon as I select the image.

george1's avatar

Ok, the only thing I can see is the request of type xhr (AJAX request object) and all the headers regarding that object. Together with the Response, Cookies and Timing. However, I don't know how these information will help me to "decipher" the problem.

jlrdw's avatar

Try uploading everything except the image, if that works there's something astray in your image uploading.

https://laravel.com/docs/6.x/requests#storing-uploaded-files

Try to set up a regular development environment search as a wamp setup.

I have no idea about file sizes using the PHP built-in server. But it would be in your PHP ini file.

george1's avatar

Hi,

I am sure there is a problem with image uploading, since before adding the upload image functionality, the form was working perfectly. The form as you may see would upload a title and a description. That works perfectly without the image upload.

jlrdw's avatar

Put enctype="multipart/form-data" in your form tag.

george1's avatar

Sorry, I realised I messet up with the code formatting. I updated it now.

Yeah, I already had the enctype on.

george1's avatar

Ok, I figured out the problem. I had to use the form element in the FormData function as it's the one containing the image files as soon as the images are being selected.

Next, add a name to the input tag which images will be chosen. (add [] after the name for multiple files).

Finally, remove the datatype JSON from the AJAX function. DIdn't figure out why yet.

@jlrdw thanks for your attmept.!

Please or to participate in this conversation.