VUE2.0利用VUE-RESOURCE上传文件到七牛

关于上传,总是有很多可以说道的。
16年底,公司项目番茄表单的前端部分,开始了从传统的jqueryvue 2.0的彻底重构。但是上传部分,无论是之前的传统版本,还是Vue新版本,都是在使用着FileAPI这款优秀的开源库,只是进行了简单的directive化。为什么呢?因为兼容性。没办法,公司项目不等同于个人项目,必须要考虑大多数浏览器。否则,上传部分完全可以利用Vue-Resource以及FormData来抛开对FileAPI的依赖。这让我深感遗憾,幸好这个简单的遗憾在个人博客Vue化重构的时候得以弥补。

上传流程

七牛上传流程
图不重要看文字
input[type="file"] change事件触发后,先去(如果是图片,可以同时通过FileReader以及readAsDataURL将图片预览在页面上)后台请求七牛的上传token,将拿到的tokenkey以及通过change传递过来的files一起appendformData中。然后将formData通过post传递给七牛,七牛在处理后将返回真正的文件地址

获取TOKEN

const qiniu = require('qiniu')
const crypto = require('crypto')
const Config = require('qiniu-config')

exports.token = function*() {
    //构建一个保存文件名
    //这里没有处理文件后缀,需要自己传递过来,然后在这里处理加在key上,非必须
    const key = crypto.createHash('md5').update(((new Date()) * 1 + Math.floor(Math.random() * 10).toString())).digest('hex')
    //Config 七牛的秘钥等配置
    const [ACCESS_KEY, SECRET_KEY, BUCKET] = [Config.accessKey, Config.secretKey, Config.bucket]
    qiniu.conf.ACCESS_KEY = ACCESS_KEY
    qiniu.conf.SECRET_KEY = SECRET_KEY
    const upToken = new qiniu.rs.PutPolicy(BUCKET + ":" + key)
    try {
        const token = upToken.token()
        return this.body = {
            key: key,
            token: token
        }
    } catch (e) {
        // throw error
    }
}

//假设api 地址是 /api/token

上传组件 UPLOAD.VUE

<template>
    <label class="mo-upload">
        <input type="file" :accept="accepts" @change="upload">
        <slot></slot>
    </label>
</template>
<style lang="scss">
    .mo-upload {
        display: inline-block;
        position: relative;
        margin-bottom: 0;
        input[type="file"] {
            display: none;
        }
        .mo-upload--label {
            display: inline-block;
            position: relative;
        }
    }
</style>
<script>
    export default {
        name : 'MoUpload',
        props : {
            accepts : { //允许的上传类型
                type : String,
                default : 'image/jpeg,image/jpg,image/png,image/gif'
            },
            flag : [String, Number], //当前上传标识,以便于在同一个监听函数中区分不同的上传域
            maxSize : {
                type : Number,
                default : 0 //上传大小限制
            },
        },
        methods: {
            upload (event) {
                let file = event.target.files[0]
                const self = this
                const flag = this.flag
                if (file) {
                    if (this.maxSize) {
                        //todo filter file
                    }
                    //filter file, 文件大小,类型等过滤
                    //如果是图片文件
                    // const reader = new FileReader()
                    // const imageUrl = reader.readAsDataURL(file)
                    // img.src = imageUrl //在预览区域插入图片

                    const formData = new FormData()
                    formData.append('file', file)

                    //获取token
                    this.$http.get(`/api/token/`)
                    .then(response => {
                        const result = response.body
                        formData.append('token', result.token)
                        formData.append('key', result.key)
                        //提交给七牛处理
                        self.$http.post('https://up.qbox.me/', formData, {
                            progress(event) {
                                //传递给父组件的progress方法
                                self.$emit('progress', parseFloat(event.loaded / event.total * 100), flag)
                            }
                        })
                        .then(response => {
                            const result = response.body
                            if (result.hash && result.key) {
                                //传递给父组件的complete方法
                                self.$emit('complete', 200 , result, flag)
                                //让当前target可以重新选择
                                event.target.value = null
                            } else {
                                self.$emit('complete', 500, result, flag)
                            }
                        }, error => self.$emit('complete', 500, error.message), flag)
                    })
                }
            }
        }
    }
</script>

父组件调用

<template>
    <section>
        ...
        <figure class="upload-preview">
            <img :src="thumbnail" v-if="thumbnail"/>
        </figure>
        <mo-upload flag="'thumbnail'" @complete="uploadComplete" @progress="uploadProgress">
            <a>选择图片文件<i class="progress" :style="{width:progress + '%'}"></i></a>
        </mo-upload>
        ...
    </section>
</template>
<script>
    import MoUpload from 'upload'
    export default {
        components : {
            MoUpload,
        },
        data () {
            return {
                thumbnail : null,
                progress : 0 //上传进度
            }
        },
        methods : {
            uploadProgress (progress, flag) {
                //这里可以通过回调的flag对不同上传域做处理
                this.progress = progress < 100 ? progress : 0;
            },
            uploadComplete(status, result, flag) {
                if (status == 200) { //
                    this.thumbnail = `domain.com/${result.key}` //七牛域名 + 返回的key 组成文件url
                } else {
                    //失败处理
                }
            },
        }
    }
</script>

小结

相比于FILEApi 或者其他上传组件,这种方法代码量最小。但是缺点也是显而易见的,大量html5 API的使用,势必会回到兼容性这个老大难上来,慎重的选择性使用吧

时间: 2025-01-19 20:14:21

VUE2.0利用VUE-RESOURCE上传文件到七牛的相关文章

JAVA如何利用JSON能上传文件?

问题描述 JAVA如何利用JSON能上传文件? 现在需要通过HTTP的POST请求实现文件发送的功能,其中发送的格式是通过JSON格式的,就是JSON里面携带的有其他参数,还有文件名和文件体,这个怎么实现? 解决方案 java上传文件到oracle数据库 解决方案二: String dataString = ""{name:""filenanme""content:""contentStr""}"

利用PUT方式上传文件的方法研究

虽然没有POST方法使用广泛,但是PUT方法却是向服务器上传文件最有效率的方法.POST上传文件时,我们通常需要将所有的信息组合成 multipart 传送过去,然后服务器再解码这些信息,解码过程则必不可少的会消耗内存和CPU资源,这种现象在上传大文件时尤其明显.而PUT方法则允许你通过与服务器建立的socket链接传递文件的内容,而不附带其他的信息. 最近一个项目上需要利用这种方式来进行文件的上传,下面介绍一下在 Apache + PHP 的环境下如何进行PUT方式的文件上传. Apache

利用Xmlhttp 分块上传文件

xml|上传 编写思路:把本地文件在客户端通过base64编码以后发送目的地.测试过程中,上传文件过大,导致超时不成功.后来经过改善.把编码分段发送.测试20M成功 编写目的:在传统的解决方案里面,一次一次选取上传可以.但是在碰到把数据库里文件路径读出来,并把这些文件上传到一个地方的时候就比较麻烦.如果得到路径一个一个去找到用ftp当然也是可以的,但每次找这些文件我看都会比较费时.这里编写这个主要就是为了通过数据库里的文件路径取得文件.把文件一次批量上传到一个地方.其主要目的还是为了锻炼一下自己

C语言 HTTP上传文件-利用libcurl库上传文件

原文  http://justwinit.cn/post/7626/ 通常情况下,一般很少使用C语言来直接上传文件,但是遇到使用C语言编程实现文件上传时,该怎么做呢? 借助开源的libcurl库,我们可以容易地实现这个功能.Libcurl是一个免费易用的客户端URL传输库,主要功能是用不同的协议连接和沟通不同的服务器,libcurl当前支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP,IMAPS, LDAP, LDAPS, POP3, POP3

利用百度云盘API上传文件至百度云盘

一.获取Access Token示例 1. 请您将以下HTTP请求直接粘贴到浏览器地址栏内,并按下回车键. https://openapi.baidu.com/oauth/2.0/authorize?response_type=token&client_id=L6g70tBRRIXLsY0Z3HwKqlRE&redirect_uri=oob&scope=netdisk 2.执行后,弹出百度登录页面,登录后弹出以下授权页面: 3.授权后,将跳转到以下百度OAuth2.0页面: 4.请

asp.net 2.0中如何实现上传文件与下载文件求具体的代码

问题描述 多多指教 解决方案 解决方案二:2.文件上传<asp:FileUploadID="FileUpload1"runat="server"/> if(FileUpload1.HasFile){FileUpload1.SaveAs(MapPath("~/UserFileHere/Image/"+FileUpload1.FileName));} 解决方案三:这个太普通的一功能解决方案四:这儿有一个,你照做,然后看看代码就可以了.解决

win2003 sp2 iis 上传文件不能超过200K的解决方案_win服务器

Windows2003系统下,上传较大的文件时,出现"Request 对象 错误 'ASP 0104 : 80004005'"错误. 更改win2003的IIS 6.0对asp的上传文件大小为200k限制,aspx的上传程序没有影响.在IIS6.0中,默认设置是特别严格和安全的,最大只能传送 204,800 个字节,这样可以最大限度地减少因以前太宽松的超时和限制而造成的攻击.IIS 6 出于安全考虑, 默认最大请求是200K(也即最大提交数据限额为200KByte,204800Byte

form表单上传文件

  表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码. 默认情况,enctype的编码格式是application/x-www-form-urlencoded,不能用于文件上传: 只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作.   利用表单上传文件的例子: <form id="form1" runat="server" enctype="m

Win 2003上传文件不能超过200k解决方法

解决|上传 问题:无法上传较大的文件"Request 对象 错误 'ASP 0104 : 80004005'"或者上传成功后,找不到文件名 更改Win 2003的IIS 6.0对asp的上传文件大小为200k限制,aspx的上传程序没有影响.在IIS6.0中,默认设置是特别严格和安全的,最大只能传送 204,800 个字节,这样可以最大限度地减少因以前太宽松的超时和限制而造成的攻击.IIS 6 出于安全考虑, 默认最大请求是200K(也即最大提交数据限额为200KByte,204800