Laravel通过ajax发送数据

I am trying to send data from my form to back-end by ajax but it doesn't send all my data.

preview of sent data

array:6 [
  "title" => "xxxxxxxxxxxx"
  "slug" => "xxxxxx"
  "description" => """xxxxxxxxxxxxxxxxx"""
  "publish" => "1"
  "user_id" => "1"
  "thumbnail" => null
]

Issues

  1. my description is in triple double qoute """ xxxx """ (not sure if it's ok)
  2. Image (thumbnail) didn't send
  3. Categories didn't send

code

form

{{ Form::model($post, array('route' => array('quickedit', $post->id), 'method' => 'POST', 'files' => true)) }}
<div class="modal-body text-left">
    {{-- show success message --}}
    <div class="msg"></div>
    <input type="hidden" name="user_id" id="user_id" value="{{Auth::user()->id}}">

    <div class="row">
        <div class="col-md-12 mt-3">
            {{ Form::label('title', 'Title') }}
            {{ Form::text('title', null, array('class' => 'form-control')) }}
        </div>
        <div class="col-md-12 mt-3">
            {{ Form::label('slug', 'Slug') }}
            {{ Form::text('slug', null, array('class' => 'form-control')) }}
        </div>
        <div class="col-md-12 mt-3">
            {{ Form::label('description', 'Description') }}
            {{ Form::textarea('description', null, array('class' => 'form-control editor')) }}
        </div>
        <div class="col-md-6 mt-3">
            <div class="row">
                @if(!empty($post->thumbnail))
                    <div class="col-md-3">
                        <img class="img-thumbnail" src="{{url('/images')}}/{{$post->thumbnail}}" alt="{{$post->title}}">
                    </div>
                    <div class="col-md-9">
                        {{ Form::label('thumbnail', 'Thumbnail') }}
                        {{ Form::file('thumbnail', array('class' => 'form-control')) }}
                    </div>
                @else
                    <div class="col-md-12">
                        {{ Form::label('thumbnail', 'Thumbnail') }}
                        {{ Form::file('thumbnail', array('class' => 'form-control')) }}
                    </div>
                @endif
            </div>
        </div>
        <div class="col-md-6 mt-3">
            {{ Form::label('publish', 'Publish') }}
            <select name="publish" id="publish" class="custom-select">
                <option value="">Select</option>
                <option value="1" {{ $post->publish == '1' ? 'selected' : '' }}>Publish</option>
                <option value="0" {{ $post->publish == '0' ? 'selected' : '' }}>Draft</option>
            </select>
        </div>
        <div class="col-md-6 mt-3">
            {{ Form::label('categories', 'Categories') }}
            <select name="categories[]" id="categories" class="custom-select selectbox" multiple>
                @foreach($categories as $category)
                <option value="{{$category->id}}">{{$category->title}}</option>
                    @if(count($category->children) > 0)
                        @foreach($category->children as $children)
                            <option class="pl-2" value="{{$children->id}}">{{$children->title}}</option>

                            @if(count($children->children) > 0)
                                @foreach($children->children as $child)
                                    <option class="pl-4" value="{{$child->id}}">{{$child->title}}</option>

                                    @if(count($child->children) > 0)
                                        @foreach($child->children as $childf)
                                            <option class="pl-5" value="{{$childf->id}}">{{$childf->title}}</option>
                                        @endforeach
                                    @endif
                                @endforeach
                            @endif
                        @endforeach
                    @endif
                @endforeach
            </select>
        </div>
    </div>
</div>
<div class="modal-footer">
    <div class="msg"></div>
</div>
{{Form::close()}}

<button class="btn btn-primary updatepost" data-id="{{$post->id}}" type="submit">Update</button>

JavaScript

<script>
$(document).ready(function() {
    $('.updatepost').click(function (event) {

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

    event.preventDefault();

    var title = $('input[name="title"]').val();
    var slug = $('input[name="slug"]').val();
    var description = $('.editor').val();
    var publish = $('#publish option:selected').val();
    var user_id = $('input[name="user_id"]').val();
    var thumbnail = $('input[name="thumbnail"]').val();
    var categories= $('#categories option:selected').val();

    // $(this).attr("disabled", "disabled");

    var prdfoId = $(this).data('id');
        $.ajax({
            url: '{{url("/admin/quickedit")}}/'+encodeURI(prdfoId),
            type: "POST",
            dataType: "json", 
            data: {
                title: title,
                slug:slug,
                description: description,
                publish: publish,
                user_id: user_id,
                thumbnail: thumbnail,
                categories: categories
            },
            success:function(data) {
                $('.msg').empty().append("Updated Successfully"); 
            }
        });
    });
});
</script>

route

Route::post('quickedit/{id}','BlogController@quickedit')->name('quickedit');

controller

public function quickedit(Request $request, $id)
    {
        dd($request->all());
        $this->validate($request, array(
            'title' => 'required',
            'slug' => 'required',
            'description' => 'required',
            'user_id' => 'required|numeric',
            'thumbnail' => 'nullable|image',
            'publish' => 'required|numeric',
        ));

        $post = Post::find($id);
        $post = Post::where('id',$id)->first();

        $post->title = $request->input('title');
        $post->slug = $request->input('slug');
        $post->description = $request->input('description');
        $post->user_id = $request->input('user_id');
        $post->publish = $request->input('publish');

        if ($request->hasFile('thumbnail')) {
            $thumbnail = $request->file('thumbnail');
            $filename = 'Post' . '-' . time() . '.' . $thumbnail->getClientOriginalExtension();
            $location = public_path('images/' . $filename);
            Image::make($thumbnail)->resize(850, 565)->save($location);
            $post->thumbnail = $filename;

            $oldFilename = $post->thumbnail;
            $post->thumbnail = $filename;
            Storage::delete($oldFilename);
        }

        $post->save();
        $post->tags()->sync($request->tags);
        $post->categories()->sync($request->categories);
    }

Any idea?

Update

Based on answer and comments the last code I ended up is:

$(document).ready(function() {
    $('.updatepost').click(function (event) {

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

    event.preventDefault();

    var title = $('input[name="title"]').val();
    var slug = $('input[name="slug"]').val();
    var description = $('.editor').val();
    var publish = $('#publish option:selected').val();
    var user_id = $('input[name="user_id"]').val();

    var thumbnail = $('input[type=file]')[0].files[0];

    var categories= [];
    $("#categories option:selected").each(function(){
        categories.push($(this).val());
    });
    categories = JSON.stringify(categories);

    //new
    var formData = new FormData();
    formData.append('thumbnail', thumbnail);
    formData.append('title', title);
    formData.append('slug', slug);
    formData.append('description', description);
    formData.append('publish', publish);
    formData.append('user_id', user_id);
    formData.append('categories', categories);
    //new


    var prdfoId = $(this).data('id');
        $.ajax({
            url: '{{url("/admin/quickedit")}}/'+encodeURI(prdfoId),
            type: "POST",
            dataType: "json", 
            data: formData,
            contentType: false,
            processData: false,
            success:function(data) {
                $('.msg').empty().append("Updated Successfully"); 
            }
        });
    });
});

The result of this code is:

array:7 [
  "thumbnail" => "undefined"
  "title" => "xxxxxxx"
  "slug" => "xxxxxxxxx"
  "description" => """
    xxxxx
   """
  "publish" => "1"
  "user_id" => "1"
  "categories" => "[]"
]

issues

  1. image is undefined
  2. categories are not passed
  3. description is in triple double qoutes """ xxxxx """

any idea?

Your quickedit method calling dd(), what dump data, then just die. Also, quickedit returns void. In must to be an object or array if you going to use AJAX+JSON.

If you send image file you need has to base64 if you need handle in json, Or need use FormData like this:

var formData = new FormData();
formData.append('image', $('input[type=file]')[0].files[0]); 

$.ajax({
    url: 'Your url here',
    data: formData,
    type: 'POST',
    contentType: false, // NEEDED, DON'T OMIT THIS (requires jQuery 1.6+)
    processData: false, // NEEDED, DON'T OMIT THIS
    // ... Other options like success and etc
});

I think, a has a simplest way make two call firs send just json data, and then secound call is send the image.

 var title = $('input[name="title"]').val();
      var slug = $('input[name="slug"]').val();
      var description = $('.editor').val();
      var publish = $('#publish option:selected').val();
      var user_id = $('input[name="user_id"]').val();
      var thumbnail = $('input[name="thumbnail"]').prop('files');

      var categories= $('#categories option:selected').val();
      var formData = new FormData();
      //Add a the file to fomr data
      formData.append('image', thumbnail[0]); 
      //And need add data like this
      formdData.append('title',title );