关于文件上传

前言:

    关于文件上传给我的如何高效率的解决一个自己从来未解决过的问题的思考,第一个是要会搜索,根据自己的问题搜索关键字,这个很大程度上决定我们解决问题的速度,比如我现在要写一个图片上传的功能,如果搜索“怎么将图片传到服务器”,会搜到有人告诉你文件用input:file上传,用formData将图片转化数据传给服务器;如果第一次做这个功能,看到这样的回答肯定还是很萌比。但是如果你搜文件上传,你马上会搜到https://juejin.im/entry/590ad4682f301e00582a78b5这篇文章,基本上就能弄明白上传该怎么做,把里面的demo复制下来试一下跑起来,再来理解原理。第二个要会找问题的突破口,比如搜到的第一个答案,说可以使用formData,你不知道formData是个啥,去搜索一下可以查到formdata传递form表单上传文件的demo,仔细看demo,它不完全能解决我的业务需求,但是这个时候看懂这个demo大概已经明白上传的原理,无非就是一个input,type为file类型的表单框用来上传本地文件,获取到上传文件的数据(input:file的change事件可以获取到上传的文件数据),然后用xml来发送数据给服务器端,xml中有onload等方法可以用来捕获到上传时的状态。

   查找资料,我们的目标最重要的是查找解决问题的思想、原理,而不是直接查找解决我们业务需求的源代码。

关键代码(待重构的上传文件的代码):

    upload(file, fun, idx, name) {
        let type = name[name.length - 1];
        let randomString = this.getRandomString()+name.splice(0, name.length - 1).join('');
        const picName = `${randomString}.${type}`;
        const token = this.token;
        const self = this;
        return new Promise((resolve, reject) => {
          let formData = new FormData();
          formData.append("file", file);
          formData.append("token", token);
          formData.append("key", picName);
          let xhr = new XMLHttpRequest();

          xhr.onload = response => {
            if (xhr.readyState == 4 && xhr.status == 200) {
              self.resultImgs[idx].showPic = true;
              let data = JSON.parse(xhr.responseText);
              resolve(data);
            } else {
              self.resultImgs.splice(idx, 1);
              alert(xhr.responseText);
            }
          };
          xhr.upload.onprogress = event => {
            let percent = Math.floor(event.loaded / event.total * 100);
            fun.apply(this, [percent, idx]);
          };
          xhr.open("POST", self.postUrl, true);
          xhr.send(formData);
        });
      },
      initReader(img1, event) {
        return new Promise((res, rej) => {
          let reader = new FileReader();
          let self = this;
          reader.readAsDataURL(img1);
          if (typeof FileReader == "undefined") {
            this.resultImgs.push({
              progress: 0,
              showPic: false,
              data: '',
              src: ""
            });
            res(reader);
          } else {
            reader.onloadend = e => {
              if (img1.type.indexOf("image/") == -1) {
                alert("请上传图片");
              } else {
                this.resultImgs.push({
                  progress: 0,
                  showPic: false,
                  data: e.target.result,
                  src: ""
                });
              }
              res(reader)
            };
          }
        })
      },
      getRandomString() {
        return (Math.random().toString(36).substr(2)) + (Math.random().toString(36).substr(2));
      },
      async addPicture(event) {
        let img1 = event.target.files[0];
        let picName = img1.name.split('.');
        const reader = await this.initReader(img1, event);
        event.target.value = ""; //解决不能重复提交同一张图片bug
        let idx = this.resultImgs.length - 1; //取得当前图片的index
        const {key} = await this.upload(img1, this.progress, idx, picName);
        let src = `${this.host}/${key}`;
        // if (typeof FileReader == "undefined") {
        //   this.resultImgs[idx].data = src;
        // }
        this.resultImgs[idx].src = src;
        this.$emit('imgChange', this.resultImgs)

      },

 其他文件上传博客参考:https://juejin.im/entry/590ad4682f301e00582a78b5

   Ajax知识体系梳理:http://louiszhai.github.io/2016/11/02/ajax/

   提高搜索能力:https://www.cnblogs.com/reblue520/p/9458791.html

   使用好google搜索:https://www.zhihu.com/question/20161362

原文地址:https://www.cnblogs.com/yy95/p/9800408.html