Ajax+tp5实现多文件上传并处理

前言

有时候我们可能会碰到这样的需求:做一个用户发布动态的功能,用户可以写一些内容和上传多张图片。

比如,像下面这样:

在给用户提供较好的交互体验的前提下,我们就只能选择使用Ajax了。

实现

HTML代码

<form enctype="multipart/form-data">
    <input type="text" id="content" name="content">
    <!-- 多文件上传 -->
    <input type="file" name="upload" id="upload" multiple>
  <button type="button" onclick="uploadHandle">提交</button>
</form>

MDN FormData 介绍

FormData 接口提供了一种表示表单数据的键值对的构造方式,经过它的数据可以使用 XMLHttpRequest.send() 方法送出,所以我们可以Ajax提交请求。

FormData.append()方法,向 FormData中添加新的属性值,FormData对应的属性值存在也不会覆盖原值,而是新增一个值,如果属性不存在则新增一项属性值。

JS代码

<script>
    var imgFiles = []; // 要上传的图片
    $('#upload').change(function () {
        let f = this.files;
        /**
         * TODO:
         * 1. 可以对上传图片的数量和图片格式进行限制
         * 2. 图片预览
         */
        for ( let item of f ){
            console.log(item);
            imgFiles.push(item);
        }
        // 解决无法上传相同图片的问题
        this.value = null;
    });

    function uploadHandle() {
        let form = new FormData();
        form.append('content', $('#content').content.val());

        $.each(imgFiles, function ( i, file ) {
            form.append('files[]', file);
        });
        submitHandle(form);
    }

    function submitHandle(formData) {
        $.ajax({
            type: 'post',
            url: '',
            data: formData,
            dataType: 'json',
            contentType: false,
            processData: false,

            success: function (msg) {
                console.log(msg);
            },
        });
    }
</script>

这里要注意几点:

  • processData:(默认: true) 默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。以上是Jquery API文档中的描述,这里我们的data是一个FormData对象,我们不希望对数据做处理。
  • contentType:(默认: "application/x-www-form-urlencoded") 发送信息至服务器时内容编码类型。因为是由form表单构造的FormData对象,且已经声明了属性enctype="multipart/form-data",所以这里设置为false。当然,我们也可以直接设置 contentType: "multipart/form-data”。

后台处理

接收数据

// tp5(ThinkPHP)
$conent = $this->request->post('content');
$files = $this->request->file('files');
// 上传处理
$fileinfo = $this->multipleImgUpload($files);
// TODO
// 原生php
$content = $_POST['content'];
$files = $_FILES['files'];

处理多图片上传

// tp5
//
要么全部上传成功,要么失败 public function multipleImgUpload($files) { $flag = true; foreach ($files as $item){ if ( $item ) { $upload = $item->validate(['size' => 1024 * 1024 * 10, 'ext' => 'jpg,jpeg,png'])->move(APP_PATH . '../public/uploads/'); if ($upload) { // 上传成功 $save_path = '/uploads/' . $upload->getSaveName(); $img_src[] = $save_path; } else { $data = ['code' => 0, 'save_path' => '', 'msg' => $item->getError()]; $flag = false; } } else { $data = ['code' => 0, 'save_path' => '', 'msg' => '文件未上传']; $flag = false; } if ( !$flag ){ break; } } if ( $flag ){ $data = ['code'=>1, 'save_path'=>$img_src, 'msg'=>'']; } return $data; }

参考

原文地址:https://www.cnblogs.com/wgxi/p/12566662.html