精华内容
下载资源
问答
  • vue怎么处理文件上传In this article, we will talk about how to handle file uploads with VueJs. We will create an images uploader that allow user to upload single or multiple images file by drag and ...

    vue怎么处理文件上传

    In this article, we will talk about how to handle file uploads with VueJs. We will create an images uploader that allow user to upload single or multiple images file by drag and drop or select file dialog.

    在本文中,我们将讨论如何使用VueJs处理文件上传。 我们将创建一个图像上传器,允许用户通过拖放或选择文件对话框上传单个或多个图像文件。

    We will then upload the selected images and display them accordingly. We will also learn to filter the upload file type, for example, we only allow images, do not allow file type like PDF.

    然后,我们将上传选定的图像并进行相应显示。 我们还将学习过滤上传文件的类型,例如,我们只允许图片,不允许像PDF这样的文件类型。

    Image uploader

    文件上传UI和API ( File Upload UI & API )

    File upload consists of two parts: the UI (front-end) and the API (back-end). We will be using VueJs to handle the UI part. We need a backend application to accept the uploaded files. You may follow the backend tutorials or download and run either one of these server side application to handle file upload for your backend:-

    文件上传由两部分组成: UI(前端)API(后端) 。 我们将使用VueJs处理UI部分。 我们需要一个后端应用程序来接受上传的文件。 您可以按照后端教程进行操作,也可以下载并运行以下任一服务器端应用程序来处理后端的文件上传:-

    We will be using File upload with Hapi.js as our backend throughout this articles. We will also learn the tricks to enable fake upload on the front-end.

    在本文中,我们将使用Hapi.js的文件上传作为我们的后端。 我们还将学习在前端启用假冒上传的技巧。

    使用Vue-Cli建立项目 ( Setup Project with Vue-Cli )

    We will be using vue-cli to scaffold Vue.js projects. We will be using the webpack-simple project template.

    我们将使用vue-cli搭建Vue.js项目。 我们将使用webpack-simplewebpack-simple项目模板。

    # install cli
    npm install vue-cli -g
    
    # then create project, with sass
    # follow the instructions to install all necessary dependencies
    vue init webpack-simple file-upload-vue

    Alright, all set. Let's proceed to create our component.

    好了,都准备好了。 让我们继续创建我们的组件。

    文件上传组件 ( File Upload Component )

    We will write our code in App.vue. Remove all the auto-generated code in the file.

    我们将在App.vue编写代码。 删除文件中所有自动生成的代码。

    <!-- App.vue -->
    
    <!-- HTML Template -->
    <template>
      <div id="app">
        <div class="container">
          <!--UPLOAD-->
          <form enctype="multipart/form-data" novalidate v-if="isInitial || isSaving">
            <h1>Upload images</h1>
            <div class="dropbox">
              <input type="file" multiple :name="uploadFieldName" :disabled="isSaving" @change="filesChange($event.target.name, $event.target.files); fileCount = $event.target.files.length"
                accept="image/*" class="input-file">
                <p v-if="isInitial">
                  Drag your file(s) here to begin<br> or click to browse
                </p>
                <p v-if="isSaving">
                  Uploading {{ fileCount }} files...
                </p>
            </div>
          </form>
      </div>
    </template>
    
    <!-- Javascript -->
    <script>
    </script>
    
    <!-- SASS styling -->
    <style lang="scss">
    </style>

    Notes:-

    笔记:-

    1. Our App.vue component consists of 3 part: template (HTML), script (Javascript) and styles (SASS).

      我们的App.vue组件由3部分组成:模板(HTML),脚本(Javascript)和样式(S​​ASS)。
    2. Our template has an upload form.

      我们的模板有一个上传表单。
    3. The form attribute enctype="multipart/form-data" is important. To enable file upload, this attribute must be set. Learn more about enctype here.

      表单属性enctype="multipart/form-data"很重要。 要启用文件上传,必须设置此属性。 在此处了解有关enctype的更多信息。
    4. We have a file input <input type="file" /> to accept file upload. The property multiple indicate it's allow multiple file upload. Remove it for single file upload.

      我们有一个文件输入<input type="file" />来接受文件上传。 属性multiple表示允许上传多个文件。 将其删除以上传单个文件。
    5. We will handle the file input change event. Whenever the file input change (someone drop or select files), we will trigger the filesChange function and pass in the control name and selected files $event.target.files, and then upload to server.

      我们将处理文件输入change事件。 每当文件输入更改(有人删除或选择文件)时,我们将触发filesChange函数并传入控件名称和所选文件$event.target.files ,然后上载到服务器。
    6. We limit the file input to accept images only with the attribute accept="image/*".

      我们将文件输入限制为仅接受具有属性accept="image/*"
    7. The file input will be disabled during upload, so user can only drop / select files again after upload complete.

      上传过程中将禁用文件输入,因此用户只能在上传完成后再次删除/选择文件。
    8. We capture the fileCount of the when file changes. We use the fileCount variable in displaying number of files uploading Uploading {{ fileCount }} files....

      我们捕获文件更改时的fileCount 。 我们使用fileCount变量来显示Uploading {{ fileCount }} files...的文件数Uploading {{ fileCount }} files...

    设置文件上传组件的样式 ( Style our File Upload Component )

    Now, that's the interesting part. Currently, our component look like this:

    现在,这是有趣的部分。 当前,我们的组件如下所示:

    File upload component without styling

    We need to transform it to look like this:

    我们需要将其转换为如下形式:

    File upload component with styling

    Let's style it!

    让我们来造型​​吧!

    <!-- App.vue -->
    ...
    
    <!-- SASS styling -->
    <style lang="scss">
      .dropbox {
        outline: 2px dashed grey; /* the dash box */
        outline-offset: -10px;
        background: lightcyan;
        color: dimgray;
        padding: 10px 10px;
        min-height: 200px; /* minimum height */
        position: relative;
        cursor: pointer;
      }
    
      .input-file {
        opacity: 0; /* invisible but it's there! */
        width: 100%;
        height: 200px;
        position: absolute;
        cursor: pointer;
      }
    
      .dropbox:hover {
        background: lightblue; /* when mouse over to the drop zone, change color */
      }
    
      .dropbox p {
        font-size: 1.2em;
        text-align: center;
        padding: 50px 0;
      }
    </style>

    With only few lines of scss, our component looks prettier now.

    仅用几行scss,我们的组件现在看起来更漂亮。

    Notes:-

    笔记:-

    1. We make the file input invisible by applying opacity: 0 style. This doesn't hide the file input, it just make it invisible.

      我们通过应用opacity: 0样式使文件输入不可见。 这不会隐藏文件输入,只会使其不可见。
    2. Then, we style the file input parent element, the dropbox css class. We make it look like a drop file zone surround with dash.

      然后,我们设置文件输入父元素dropbox css类的样式。 我们使它看起来像是一个带有短划线的拖放文件区域。
    3. Then, we align the text inside dropbox to center.

      然后,我们将Dropbox中的文本对齐到中心。

    文件上传组件代码 ( File Upload Component Code )

    Let's proceed to code our component.

    让我们继续编写组件代码。

    <!-- App.vue -->
    ...
    
    <!-- Javascript -->
    <script>
      import { upload } from './file-upload.service';
    
      const STATUS_INITIAL = 0, STATUS_SAVING = 1, STATUS_SUCCESS = 2, STATUS_FAILED = 3;
    
      export default {
        name: 'app',
        data() {
          return {
            uploadedFiles: [],
            uploadError: null,
            currentStatus: null,
            uploadFieldName: 'photos'
          }
        },
        computed: {
          isInitial() {
            return this.currentStatus === STATUS_INITIAL;
          },
          isSaving() {
            return this.currentStatus === STATUS_SAVING;
          },
          isSuccess() {
            return this.currentStatus === STATUS_SUCCESS;
          },
          isFailed() {
            return this.currentStatus === STATUS_FAILED;
          }
        },
        methods: {
          reset() {
            // reset form to initial state
            this.currentStatus = STATUS_INITIAL;
            this.uploadedFiles = [];
            this.uploadError = null;
          },
          save(formData) {
            // upload data to the server
            this.currentStatus = STATUS_SAVING;
    
            upload(formData)
              .then(x => {
                this.uploadedFiles = [].concat(x);
                this.currentStatus = STATUS_SUCCESS;
              })
              .catch(err => {
                this.uploadError = err.response;
                this.currentStatus = STATUS_FAILED;
              });
          },
          filesChange(fieldName, fileList) {
            // handle file changes
            const formData = new FormData();
    
            if (!fileList.length) return;
    
            // append the files to FormData
            Array
              .from(Array(fileList.length).keys())
              .map(x => {
                formData.append(fieldName, fileList[x], fileList[x].name);
              });
    
            // save it
            this.save(formData);
          }
        },
        mounted() {
          this.reset();
        },
      }
    
    </script>

    Notes:-

    笔记:-

    1. Our component will have a few statuses: STATUS_INITIAL, STATUS_SAVING, STATUS_SUCCESS, STATUS_FAILED, the variable name is pretty expressive themselves.

      我们的组件将具有以下几种状态:STATUS_INITIAL,STATUS_SAVING,STATUS_SUCCESS,STATUS_FAILED,变量名本身很漂亮。
    2. Later on, we will call the Hapi.js file upload API to upload images, the API accept a field call photos. That's our file input field name.

      稍后,我们将调用Hapi.js文件上传 API来上传图片,该API接受现场调用photos 。 那就是我们的文件输入字段名称。
    3. We handle the file changes with the filesChange function. FileList is an object returned by the files property of the HTML element. It allow us to access the list of files selected with the element. Learn more [here]((https://developer.mozilla.org/en/docs/Web/API/FileList).

      我们使用filesChange函数处理文件更改。 FileList是HTML元素的files属性返回的对象。 它允许我们访问用元素选择的文件的列表。 在此处[( https://developer.mozilla.org/en/docs/Web/API/FileList )了解更多信息。
    4. We then create a new FormData, and append all our photos files to it. FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values. Learn more here.

      然后,我们创建一个新的FormData ,并将所有photos文件附加到该文件。 FormData接口提供了一种轻松构造一组代表表单字段及其值的键/值对的方法。 在这里了解更多。
    5. The save function will call our file upload service (hang on, we will create the service next!). We also set the status according to the result.

      save功能将调用我们的文件上传服务(继续,我们接下来将创建该服务!)。 我们还根据结果设置状态。
    6. mount() is the vue component life cycle hook. During that point, we will set our component status to initial state.

      mount()是vue组件生命周期挂钩。 在此期间,我们将组件状态设置为初始状态。

    文件上传服务 ( File Upload Service )

    Let's proceed to create our service. We will be using axios to make HTTP calls.

    让我们继续创建我们的服务。 我们将使用axios进行HTTP调用。

    安装axios (Install axios)

    # install axios
    npm install axios --save

    服务 (Service)

    // file-upload.service.js
    
    import * as axios from 'axios';
    
    const BASE_URL = 'http://localhost:3001';
    
    function upload(formData) {
        const url = `${BASE_URL}/photos/upload`;
        return axios.post(url, formData)
            // get data
            .then(x => x.data)
            // add url field
            .then(x => x.map(img => Object.assign({},
                img, { url: `${BASE_URL}/images/${img.id}` })));
    }
    
    export { upload }

    Nothing much, the code is pretty expressive itself. We upload the files, wait for the result, map it accordingly.

    没什么,代码本身也很容易表达。 我们上传文件,等待结果,并相应地映射它。

    You may run the application now with npm run dev command. Try uploading a couple of images, and it's working! (Remember to start your backend server)

    您现在可以使用npm run dev命令运行该应用程序。 尝试上传几个图像,它可以正常工作! (记住要启动后端服务器)

    显示成功和失败的结果 ( Display Success and Failed Result )

    We can upload the files successfully now. However, there's no indication in UI. Let's update our HTML template.

    我们现在可以成功上传文件。 但是,UI中没有指示。 让我们更新我们HTML模板。

    <!-- App.vue -->
    
    <!-- HTML Template -->
    <template>
      <div id="app">
        <div class="container">
          ...form...
    
          <!--SUCCESS-->
          <div v-if="isSuccess">
            <h2>Uploaded {{ uploadedFiles.length }} file(s) successfully.</h2>
            <p>
              <a href="javascript:void(0)" @click="reset()">Upload again</a>
            </p>
            <ul class="list-unstyled">
              <li v-for="item in uploadedFiles">
                <img :src="item.url" class="img-responsive img-thumbnail" :alt="item.originalName">
              </li>
            </ul>
          </div>
          <!--FAILED-->
          <div v-if="isFailed">
            <h2>Uploaded failed.</h2>
            <p>
              <a href="javascript:void(0)" @click="reset()">Try again</a>
            </p>
            <pre>{{ uploadError }}</pre>
          </div>
        </div>
      </div>
    </template>

    Notes:-

    笔记:-

    1. Display the uploaded image when upload successfully.

      成功上传后显示上传的图像。
    2. Display the error message when upload failed.

      上载失败时显示错误消息。

    伪造前端上传 ( Fake the Upload in Front-end )

    If you are lazy to start the back-end application (Hapi, Express, etc) to handle file upload. Here is a fake service to replace the file upload service.

    如果您懒于启动后端应用程序(Hapi,Express等)来处理文件上传。 这是一项伪造的服务,用来代替文件上传服务。

    // file-upload.fake.service.js
    
    function upload(formData) {
        const photos = formData.getAll('photos');
        const promises = photos.map((x) => getImage(x)
            .then(img => ({
                id: img,
                originalName: x.name,
                fileName: x.name,
                url: img
            })));
        return Promise.all(promises);
    }
    
    function getImage(file) {
        return new Promise((resolve, reject) => {
            const fReader = new FileReader();
            const img = document.createElement('img');
    
            fReader.onload = () => {
                img.src = fReader.result;
                resolve(getBase64Image(img));
            }
    
            fReader.readAsDataURL(file);
        })
    }
    
    function getBase64Image(img) {
        const canvas = document.createElement('canvas');
        canvas.width = img.width;
        canvas.height = img.height;
    
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0);
    
        const dataURL = canvas.toDataURL('image/png');
    
        return dataURL;
    }
    
    export { upload }

    Came across this solution in this Stackoverflow post. Pretty useful. My online demo is using this service.

    在此Stackoverflow帖子中介绍了此解决方案。 很有用。 我的在线演示正在使用此服务。

    Basically, what the code do is read the source, draw it in canvas, and save it as data url with the canvas toDataURL function. Learn more about canvas here.

    基本上,代码要做的是读取源代码,将其绘制在画布中,然后使用canvas toDataURL函数将其另存为数据url。 在此处了解有关画布的更多信息。

    Now you can swap the real service with the fake one.

    现在,您可以将真实服务与假服务交换。

    <!-- App.vue -->
    ...
    
    <!-- Javascript -->
    <script>
      // swap as you need
      import { upload } from './file-upload.fake.service'; // fake service
      // import { upload } from './file-upload.service';   // real service
    </script>
    
    ...
    

    Done! Stop your backend API, refresh your browser, you should see our app is still working, calling fake service instead.

    做完了! 停止后端API,刷新浏览器,您应该会看到我们的应用程序仍在运行,请转而使用假服务。

    奖励:延迟您的承诺 ( Bonus: Delay Your Promises )

    Sometimes, you may want to delay the promises to see the state changes. In our case, the file upload may complete too fast. Let's write a helper function for that.

    有时,您可能希望延迟查看状态更改的承诺。 在我们的情况下,文件上传可能会完成得太快。 让我们为此编写一个辅助函数。

    // utils.js
    
    // utils to delay promise
    function wait(ms) {
        return (x) => {
            return new Promise(resolve => setTimeout(() => resolve(x), ms));
        };
    }
    
    export { wait }
    

    Then, you can use it in your component

    然后,您可以在组件中使用它

    <!-- App.vue -->
    ...
    
    <!-- Javascript -->
    <script>
      import { wait } from './utils';
      ...
    
      save(formData) {
         ....
    
            upload(formData)
              .then(wait(1500)) // DEV ONLY: wait for 1.5s 
              .then(x => {
                this.uploadedFiles = [].concat(x);
                this.currentStatus = STATUS_SUCCESS;
              })
             ...
    
          },
    </script>

    摘要 ( Summary )

    That's it. This is how you can handle file upload without using any 3rd party libraries and plugins in Vue. It isn't that hard right?

    而已。 这样就可以在不使用Vue中任何第三方库和插件的情况下处理文件上传。 这不是很难吗?

    Happy coding!

    编码愉快!

    The UI (Front-end)

    用户界面(前端)

    The API (Back-end) Tutorials and Sourcode

    API(后端)教程和源代码

    翻译自: https://scotch.io/tutorials/how-to-handle-file-uploads-in-vue-2

    vue怎么处理文件上传

    展开全文
  • 在某些业务,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表格数据、上传影音文件等。如果文件体积比较大,或者网络条件不好时,上传的时间会比较长(要传输更多的报文,丢包重传的概率也更大)...

    最近遇见一个需要上传百兆大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现。

    在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表格数据、上传影音文件等。如果文件体积比较大,或者网络条件不好时,上传的时间会比较长(要传输更多的报文,丢包重传的概率也更大),用户不能刷新页面,只能耐心等待请求完成。

    下面从文件上传方式入手,整理大文件上传的思路,并给出了相关实例代码,由于PHP内置了比较方便的文件拆分和拼接方法,因此服务端代码使用PHP进行示例编写。

    本文相关示例代码位于github上,主要参考

    聊聊大文件上传

    大文件切割上传

    文件上传的几种方式

    首先我们来看看文件上传的几种方式。

    普通表单上传

    使用PHP来展示常规的表单上传是一个不错的选择。首先构建文件上传的表单,并指定表单的提交内容类型为enctype="multipart/form-data",表明表单需要上传二进制数据。

    然后编写index.php上传文件接收代码,使用move_uploaded_file方法即可(php大法好…)

    form表单上传大文件时,很容易遇见服务器超时的问题。通过xhr,前端也可以进行异步上传文件的操作,一般由两个思路。

    文件编码上传

    第一个思路是将文件进行编码,然后在服务端进行解码,之前写过一篇在前端实现图片压缩上传的博客,其主要实现原理就是将图片转换成base64进行传递

    varimgURL = URL.createObjectURL(file);

    ctx.drawImage(imgURL, 0, 0);

    // 获取图片的编码,然后将图片当做是一个很长的字符串进行传递

    vardata= canvas.toDataURL( "image/jpeg", 0.5);

    在服务端需要做的事情也比较简单,首先解码base64,然后保存图片即可

    $imgData = $_REQUEST[ 'imgData'];

    $base64 = explode( ',', $imgData)[ 1];

    $img = base64_decode($base64);

    $url = './test.jpg';

    if(file_put_contents($url, $img)) {

    exit(json_encode( array(

    url => $url

    )));

    }

    base64编码的缺点在于其体积比原图片更大(因为Base64将三个字节转化成四个字节,因此编码后的文本,会比原文本大出三分之一左右),对于体积很大的文件来说,上传和解析的时间会明显增加。

    更多关于base64的知识,可以参考Base64笔记。

    除了进行base64编码,还可以在前端直接读取文件内容后以二进制格式上传

    // 读取二进制文件

    functionreadBinary(text){

    vardata = newArrayBuffer(text.length);

    varui8a = newUint8Array(data, 0);

    for( vari = 0; i < text.length; i++){

    ui8a[i] = (text.charCodeAt(i) & 0xff);

    }

    console.log(ui8a)

    }

    varreader = newFileReader;

    reader. = function{

    readBinary( this.result) // 读取result或直接上传

    }

    // 把从input里读取的文件内容,放到fileReader的result字段里

    reader.readAsBinaryString(file);

    formData异步上传

    FormData对象主要用来组装一组用 发送请求的键/值对,可以更加灵活地发送Ajax请求。可以使用FormData来模拟表单提交。

    letfiles = e.target.files // 获取input的file对象

    letformData = newFormData;

    formData.append( 'file', file);

    axios.post(url, formData);

    服务端处理方式与直接form表单请求基本相同。

    iframe无刷新页面

    在低版本的浏览器(如IE)上,xhr是不支持直接上传formdata的,因此只能用form来上传文件,而form提交本身会进行页面跳转,这是因为form表单的target属性导致的,其取值有

    _self,默认值,在相同的窗口中打开响应页面

    _blank,在新窗口打开

    _parent,在父窗口打开

    _top,在最顶层的窗口打开

    framename,在指定名字的iframe中打开

    如果需要让用户体验异步上传文件的感觉,可以通过framename指定iframe来实现。把form的target属性设置为一个看不见的iframe,那么返回的数据就会被这个iframe接受,因此只有该iframe会被刷新,至于返回结果,也可以通过解析这个iframe内的文本来获取。

    functionupload{

    varnow = + newDate

    varid = 'frame'+ now

    $( "body").append( `<iframe style="display:none;" name="${id}" id="${id}" />`);

    var$form = $( "#myForm")

    $form.attr({

    "action": '/index.php',

    "method": "post",

    "enctype": "multipart/form-data",

    "encoding": "multipart/form-data",

    "target": id

    }).submit

    $( "#"+id).on( "load", function{

    varcontent = $( this).contents.find( "body").text

    try{

    vardata = JSON.parse(content)

    } catch(e){

    console.log(e)

    }

    })

    }

    大文件上传

    现在来看看在上面提到的几种上传方式中实现大文件上传会遇见的超时问题,

    表单上传和iframe无刷新页面上传,实际上都是通过form标签进行上传文件,这种方式将整个请求完全交给浏览器处理,当上传大文件时,可能会遇见请求超时的情形

    通过fromData,其实际也是在xhr中封装一组请求参数,用来模拟表单请求,无法避免大文件上传超时的问题

    编码上传,我们可以比较灵活地控制上传的内容

    大文件上传最主要的问题就在于:在同一个请求中,要上传大量的数据,导致整个过程会比较漫长,且失败后需要重头开始上传。试想,如果我们将这个请求拆分成多个请求,每个请求的时间就会缩短,且如果某个请求失败,只需要重新发送这一次请求即可,无需从头开始,这样是否可以解决大文件上传的问题呢?

    综合上面的问题,看来大文件上传需要实现下面几个需求

    支持拆分上传请求(即切片)

    支持断点续传

    支持显示上传进度和暂停上传

    接下来让我们依次实现这些功能,看起来最主要的功能应该就是切片了。

    文件切片

    参考: 大文件切割上传

    编码方式上传中,在前端我们只要先获取文件的二进制内容,然后对其内容进行拆分,最后将每个切片上传到服务端即可。

    在Java中,文件FIle对象是Blob对象的子类,Blob对象包含一个重要的方法slice,通过这个方法,我们就可以对二进制文件进行拆分。

    下面是一个拆分文件的示例,对于up6来说开发者不需要关心拆分的细节,由控件帮助实现,开发者只需要关心业务逻辑即可。

    控件上传的时候会为每一个文件块数据添加相关的信息,开发者在服务端接收到数据后可以自已进行处理。

    服务器接收到这些切片后,再将他们拼接起来就可以了,下面是PHP拼接切片的示例代码

    对于up6来说,开发人员不需要进行拼接,up6已经提供了示例代码,已经实现了这个逻辑。

    保证唯一性,控件会为每一个文件块添加信息,如块索引,块MD5,文件MD5

    断点续传

    up6自带续传功能,up6在服务端已经保存了文件的信息,在客户端也保存了文件的进度信息。在上传时控件会自动加载文件进度信息,开发者不需要关心这些细节。在文件块的处理逻辑中只需要根据文件块索引来识别即可。

    此时上传时刷新页面或者关闭浏览器,再次上传相同文件时,之前已经上传成功的切片就不会再重新上传了。

    服务端实现断点续传的逻辑基本相似,只要在getUploadSliceRecord内部调用服务端的查询接口获取已上传切片的记录即可,因此这里不再展开。

    此外断点续传还需要考虑切片过期的情况:如果调用了mkfile接口,则磁盘上的切片内容就可以清除掉了,如果客户端一直不调用mkfile的接口,放任这些切片一直保存在磁盘显然是不可靠的,一般情况下,切片上传都有一段时间的有效期,超过该有效期,就会被清除掉。基于上述原因,断点续传也必须同步切片过期的实现逻辑。

    续传效果

     

    上传进度和暂停

    通过xhr.upload中的progress方法可以实现监控每一个切片上传进度。

    上传暂停的实现也比较简单,通过xhr.abort可以取消当前未完成上传切片的上传,实现上传暂停的效果,恢复上传就跟断点续传类似,先获取已上传的切片列表,然后重新发送未上传的切片。

    由于篇幅关系,上传进度和暂停的功能这里就先不实现了。

    实现效果:

     

    小结

    目前社区已经存在一些成熟的大文件上传解决方案,如七牛SDK,腾讯云SDK等,也许并不需要我们手动去实现一个简陋的大文件上传库,但是了解其原理还是十分有必要的。

    本文首先整理了前端文件上传的几种方式,然后讨论了大文件上传的几种场景,以及大文件上传需要实现的几个功能

    通过Blob对象的slice方法将文件拆分成切片

    整理了服务端还原文件所需条件和参数,演示了PHP将切片还原成文件

    通过保存已上传切片的记录来实现断点续传

    还留下了一些问题,如:合并文件时避免内存溢出、切片失效策略、上传进度暂停等功能,并没有去深入或一一实现,继续学习吧

    后端代码逻辑大部分是相同的,目前能够支持MySQL,Oracle,SQL。在使用前需要配置一下数据库,可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/12/java-http%E5%A4%A7%E6%96%87%E4%BB%B6%E6%96%AD%E7%82%B9%E7%BB%AD%E4%BC%A0%E4%B8%8A%E4%BC%A0/

    展开全文
  • 前端vue怎么实现文件上传

    千次阅读 2018-06-06 16:49:08
    1、data.js定义export default{ init :function(){ return{ fileList:[], token:{ accessToken:'' } } } }1...

    1、data.js中定义

    export default{
         init :function(){
              return{
                     fileList:[],
                     token:{
                        accessToken:''
                     }
               }
         }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2、xxx.vue中

    <template>
        <section>
            <el-row> 
                 <el-form-item>
                      <el-upload 
                             class="upload-demo"  
                             action="http://192.168.400.56:9000/file/rest/common/uploadFilesClientByArray" 
                             :data='token'
                             :on-change="handleChange" 
                             :on-remove="handleRemove" 
                             :file-list="fileList">
                            <el-button size="small" type="primary">上传附件</el-button> 
                      </el-upload>  
                     </el-form-item> 
            </el-row>
        </section>
    </template>
    <script>
        import data from './data';
        import methods from './method';
        export default{
            data() {  
                return data.init(); 
            },
            methods:methods
        }
    </script>
    <style>
    </style>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    注:1、接口接收accessToken的值放在请求头中,将上面的:data=”token” 改成:headers=”token”即可 
    2、action即为附件的上传接口的详细地址 
    3、data是传递参数的 
    4、fileList是上传回调的数据数组

    3、method.js中

    export default{
        handleChange(file, fileList) {
            this.fileList = fileList; 
            var ids=handleUpOrDel(fileList);  
        },  
        handleRemove(file, fileList){
            this.fileList = fileList;  
            var ids=handleUpOrDel(fileList);
        },
        handleUpOrDel(fileList){
           let ids="";
           if(fileList){
                for(var i =0; i < fileList.length; i++){ 
                    console.log(fileList[i].response);
                    var obj = fileList[i].response; 
                    if(obj){
                        if(obj.code){
                             ids +=obj.record.successResponse[0].id;
                             if(i < fileList.length - 1){
                                ids +=",";
                             }
                        }
                    }
                } 
            }
            return ids;  
        }
    }
    展开全文
  • vue upload 上传文件之删除文件

    千次阅读 2020-07-16 23:07:14
    在做图片上传时,用Element UI 组件库 upload组件,图片...那么接下来看看在项目中怎么实现的吧 首先自己手写了一个删除的方法,循环遍历外边的一层 当点击 ‘X’时,获取当前文件的图片路径,和之前的图片List进行比.

    在做图片上传时,用Element UI 组件库 upload组件,图片上传时通过文档流的形式,例如下面代码中的action的地址,需要提前协商好,但是Vue官网对删除只介绍了其中的一些并没有实现图片的删除功能,

     handleRemove(file, fileList) {
       console.log(file, fileList);
     },
    

    在这里插入图片描述
    那么接下来看看在项目中怎么实现的吧

    1. 首先自己手写了一个删除的方法,循环遍历外边的一层
    2. 当点击 ‘X’时,获取当前文件的图片路径,和之前的图片List进行比较做处理
      在这里插入图片描述
    <div
     v-for="item in dataForm.imageUrl"
     :key="item"
     style="position: relative;float:left;margin:20px 10px"
    >
     <img :src="item" class="avatar" />
     <i
       class="el-icon-close"
       @click="deleteClick(item)"
       style=" position: absolute;top: -8px; left: 60px; cursor: pointer;"
     ></i>
    </div>
    

    在删除方法中代码实现

    let newArray = [];
      this.dataForm.imageUrl.forEach(i => {
        if (i != item) {
          newArray.push(i);
        }
        this.dataForm.imageUrl = newArray;
      });
    

    最后实现的效果
    在这里插入图片描述
    希望对大家有所帮助~

    展开全文
  • 平时工作经常会遇到需要上传文件的情况,如果你用ant design 或者element ,它们都提供了上传的组件。 我们分别来看一下element 和 antd 手动上传怎么处理: ant design 手动上传文件 antd官网有手动上传的demo:...
  • 我们经常使用表单来上传数据,以及上传文件,那么怎么在表单提交成功的时候接受服务器的响应,并作出相应操作.当然使用一般jQuery上传对象的格式也是可以的,如果使用传统的表单上传呢?这种方式可以提交,那么问题来了,...
  • Vue axios 提交表单数据(含上传文件) 转载 2017-07-06 作者:守候你的季节 我要评论 本篇文章主要介绍了Vue axios 提交表单数据(含上传文件),具有一定的参考价值,有兴趣的可以了解一下 我们经常使用表单来...
  • 文件上传是我们作为开发者在日常工作经常遇到的一个需求,各个流行的组件库也都有现成的组件可以很方便的直接调用。具体的用法不再赘述,小伙伴们可以在组件库查看demo,这里笔者主要介绍下如何实现一个Upload...
  • 好长时间没有更新文章了,今天写点关于js上传文件的问题上传文件用input type=file,通过onchange事件获取到上传文件的信息,这个大家都知道。那么通过ajax上传到服务器传formdata格式该怎么写呢?首先,new一个...
  • 之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目,不论是用户头像上传,还是各种媒体文件上传,以及各种个性的业务需求,都能得到...
  • vue中文件传到后端去? 怎么触发这个动作(传到后端的这个动作) 方法一 增加按钮 方法二 直接在这个控件上增加一个事件监听;当这个控件的值发生变化的时候,就去触发上传的动作 在vue中的input标签中增加一个...
  • 好长时间没有更新文章了,今天写点关于js上传文件的问题上传文件用input type=file,通过onchange事件获取到上传文件的信息,这个大家都知道。那么通过ajax上传到服务器传formdata格式该怎么写呢?首先,new一个...
  • 做过几个Vue 小项目,每次打包后都要手动通过FTP把打包后的文件上传到服务器, 嫌麻烦吃后,学习了一下打包自动上传工具,SCP2 。下面记录一下SCP2怎么配置和使用: 1、安装: $ npm install scp2 -g 注意:-...
  • 在Jquery时代,做上传功能,一般找jQuery插件就够了,很少有人去探究上传文件插件到底是怎么做的。 简单列一下我们要做的技术点和功能点 使用技术 客户端使用vue.js 3.0,并使用vue3新增的功能:Composition API ,...
  • 之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目,不论是用户头像上传,还是各种媒体文件上传,以及各种个性的业务需求,都能得到...
  • 文件上传出现:Required request part ‘file’ is not present 这个错误且后端接口通过postman能够请求成功,但前端怎么上传不成功,明明配置好了请求头而且数据也放置在了data如: 问题解决 通过FormData...
  • 首先上传组件一定要绑定这两个属性: ref,和 :file-list,如果没有ref,即使 用this.$refs.upload.clearFiles()也不行,因为这时候this.$refs为空对象,绑定完之后可以把this.$refs打印出来看看,如下图: ...
  • 项目多出有上传文件的需求,使用现有的UI框架实现的过程,不知道什么原因,总会有一些莫名其妙的bug。比如用某上传组件,明明注明(:multiple=”false”),可实际上还是能多选,上传的时候依然发送了多个文件;...
  • 写在最前面的话:鉴于近期很多的博友讨论,说我按照文章的一步一步来,弄好之后,怎么会提示后端配置项http错误,文件上传会提示上传错误。这里提别申明一点,ueditor在前端配置好后,需要与后端部分配合进行,后端...
  • 在Jquery时代,做上传功能,一般找jQuery插件就够了,很少有人去探究上传文件插件到底是怎么做的。简单列一下我们要做的技术点和功能点使用技术客户端使用vue.js 3.0,并使用vue3新增的功能:Composition API ,服务器...
  • vue用el-upload实现文件上传

    千次阅读 2020-06-05 22:22:11
    因为我是vue+springboot前后分离,要跨域,就不能用默认的action写请求地址,我用axios时最困扰的就是怎么拿到那个真实的文件,然后给传给后台。 其实可以通过自带的onchanne触发方法获得文件列表,文件信息那个...
  • 在Jquery时代,做上传功能,一般找jQuery插件就够了,很少有人去探究上传文件插件到底是怎么做的。简单列一下我们要做的技术点和功能点使用技术客户端使用vue.js 3.0,并使用vue3新增的功能:Composition API ,服务器...
  • 一、到github或者码云上建立一个私有或公开仓库(这里以github为例) 创建成功后我们得到了一个仓库地址,github上的操作完成,现在去项目内捣鼓 ...2、进入需要上传的项目文件夹上传XXX项目,在本地就进去XX...
  • 但是,最近项目,需要在富文本中上传音频文件,但是vue-quill-editor这个富文本仅支持图片,视频上传;所以这个功能需要自定义。怎么实现这个功能?写一个只能上传音频的组件,并且隐藏在富文本插件的toolbar定义...
  • vue 选择本地文件目录

    千次阅读 热门讨论 2020-10-15 15:12:09
    但有时候会有一些需求是不能简单选择一个文件上传就能解决的,如果要本地文件目录文件进行相关的逻辑处理,就比较麻烦,然后我做了本地一个文件目录选择的例子,只要得到目录地址,后面想怎么操作就看大家发挥了...
  • 绑定事件无效的问题,不仅仅是Vue中才会出现的,写原生js时同样是上传文件后将无法触发事件,简单查阅资料,似乎与上传的DOM组件相关,因项目紧急也没有深究。 怎么解决事件不触发的问题? 网上大多文章说是要移除...
  • 一、到github或者码云上建立一个私有或公开仓库(这里以github为例)创建成功后我们得到了一个仓库地址,github上的操作完成,现在去项目内捣鼓二、提交本地文件并推送1、我是用命令的格式上传项目,首先要安装github :...

空空如也

空空如也

1 2 3 4
收藏数 72
精华内容 28
关键字:

vue中怎么上传文件

vue 订阅