猿问

怎样在AJAX异步上传的时候给后端拿到图片文件?

前端页面:

      <form  id="file-upload-form-1" method="POST" action="/admin/upload/file"
            class="form-horizontal" enctype="multipart/form-data">
        <input type="hidden" id="file-upload" name="_token" value="{{ csrf_token() }}">
        <input type="hidden" id="folder" name="folder" value="{{ $folder }}">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">
            &times;
          </button>
          <h4 class="modal-title">上传新的文件</h4>
        </div>
        <div class="modal-body">
          <div class="form-group">
            <label for="file" class="col-sm-3 control-label">
              文件
            </label>
            <div class="col-sm-8" id="photo1">
              <input type="file" id="file" name="file" >
            </div>
          </div>
          <div class="form-group">
            <label for="file_name" class="col-sm-3 control-label">
              选择上传到的文件夹/命名并上传或直接命名并上传
            </label>
            <div class="col-sm-4">
              <input type="text" id="file_name" name="file_name"
                     class="form-control">
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">
            取消
          </button>
            <button type="button" class="btn btn-default"  onclick="uploadPhoto()">
                取
            </button>
          <button type="submit" class="btn btn-primary" onclick="handle_upload_image()" >
            上传文件
          </button>
        </div>
      </form>

主要是那几个input,尤其是 <input type="file" id="file" name="file" >

ajax的代码:

    function uploadPhoto() {
        const file = $("#file").val();
        var file_upload = $("#file-upload").val();
        var file_name = $("#file_name").val();
        var data = {};
        data.file = file;
        data.file_name = file_name;
        data.file_upload = $("#file-upload").val();
        $.ajax({
            url:"/admin/ajaxupload/file",
            type:"POST",
            data:data,
            dataType:"JSON",
            success:function(aj){
                alert(aj);
                $('#page_image').html($('#file_name').text());
            },
            error:function(aj){
                alert("ajax产生错误"+aj);
            }
        });
    }

这里的值都抓取到了,用控制台输出看是看得到的,也就是说AJAX部分的代码没毛病,

之后是后端的代码:(先看的是我没有用AJAX,直接上传图片的函数,)

    public function uploadFile(UploadFileRequest $request)
    {
        $file = $_FILES['file'];
        $fileName = $request->get('file_name');
        $fileName = $fileName ?: $file['name'];
        $path = str_finish($request->get('folder'), '/') . $fileName;
        $content = File::get($file['tmp_name']);
        $homes = home::where('image_name', $fileName)->get();
        if ($homes->count()) {
            $error = "File already exists";
            return redirect()
                ->back()
                ->withErrors([$error]);
        }
        $syncfileditle = home::create([
            'image_name' => $fileName,
            'show_image' => 0,
            'webPath' => $path
        ]);
        $result = $this->manager->saveFile($path, $content);
        if ($result === true) {
            return redirect()
                ->back()
                ->withSuccess("文件 '$syncfileditle->image_name' 已上传");
        }

        $error = $result ?: "上传文件引发了一个错误";
        return redirect()
            ->back()
            ->withErrors([$error]);
    }

注!!!这里我是用超级变量$_FILES[]去拿到前端传过来的file,之后再通过$result = $this->manager->saveFile($path, $content);存储,但是在AJAX的时候用同样的方法取值,通过PosteMan去调试
达到如下反馈:

说明这种( $file = $_FILES['file'];)取得file的方式是不对的,(PS:file_name等别的 $fileName = $request->input('file_name');这样获取的值并没有问题,能成功接受),

最后为了详细点,把保存用的函数贴出来:

 public function saveFile($path, $content)
    {
        $path = $this->cleanFolder($path);

        if ($this->disk->exists($path)) {
            return "File already exists.";
        }

        return $this->disk->put($path, $content);
    }

所以求问应该在后端怎么正确的接收file文件,(这样子不用ajax,直接从前端submit的话是能成功存储的)

听从各位建议之后把ajax改成formData了:

 var formData = new FormData($("#file-upload-form-1"));
        $.ajax({
            url:"/admin/ajaxupload/file",
            type:"POST",
            data:formData,
            cache:false,         //不设置缓存
            processData: false,  // 不处理数据
            contentType: false,   // 不设置内容类型
//            dataType:"JSON",
            success:function(aj){
                alert(aj);
                $('#page_image').html($('#file_name').text());
            },
            error:function(aj){
                alert("ajax产生错误"+aj);
            }
        });

但是后端还是讲Undefined index: file,没有任何变化呀。。。。QAQ

按照大神的博客进行了修改,于是ajax的函数现在变成酱紫了:

    function uploadPhoto() {
        const file = $("#file-front").val();
        var file_upload = $("#file-upload").val();
        var file_name = $("#file_name").val();

        //用formData格式传参
        var formData = new FormData($("#file-upload-form-1"));
        formData.append('file_name',file_name);
        formData.append('file_upload',file_upload);
        var filearr = [];
        var myfile = document.getElementById('file-front');
        filearr.push(myfile);
        formData.append("file", myfile); //用append添加到formData中,就得用户最重要提交的图片了

        //用json格式的对象传递参数
        var data = {};
        data.file = file;
        data.file_name = file_name;
        data.file_upload = $("#file-upload").val();


        $.ajax({
            url:"/admin/ajaxupload/file",
            type:"POST",
            data:formData,
//            dataType:"JSON",

            cache:false,         //不设置缓存
            processData: false,  // 不处理数据
            contentType: false,   // 不设置内容类型

            success:function(aj){
                console.log(formData.get("file_name")+filearr+"--------"+myfile);
                alert(aj);
                $('#page_image').html($('#file_name').text());
            },
            error:function(aj){
                alert("ajax产生错误"+aj);
            }
        });
    }

贴一下后端 var_dump($_FILES); var_dump($_REQUEST);回来的数据:

array(0) {
}
array(3) {
  ["file_name"]=>
  string(6) "w1.jpg"
  ["file_upload"]=>
  string(40) "0n3QmJF8cxYdWDju1sKPgDeARHY3cD9hc5pkrJeG"
  ["file"]=>
  string(25) "[object HTMLInputElement]"
}
慕神8447489
浏览 1626回答 4
4回答

白衣染霜花

关键字formdata

波斯汪

异步上传文件可以用FormData var formData=new FormData(); formData.append('file',$("#file")[0]); data.file = formData

翻翻过去那场雪

ajax,header没设置成表单数据类型
随时随地看视频慕课网APP
我要回答