当前位置: 首页 > Web前端 > vue.js

vue上传图片到七牛云的思路与实现

时间:2023-03-31 20:58:26 vue.js

.upload{width:600px;margin:0auto;}.avatar-uploader.el-upload{border:5pxdashed#ca1717!important;边界半径:6px;游标:指针;位置:相对;overflow:hidden;}.avatar-uploader.el-upload:hover{border-color:#409EFF;}.avatar-uploader-icon{font-size:28px;颜色:#8c939d;宽度:178px;高度:178px;行高:178px;178像素;高度:178px;display:block;}本文分为思路和代码。思路主要是思路和代码的混合,主要侧重于讲解思路;代码是注释和代码的结合,主要是展示代码。一、思路方法一:上传图片思路(通过前台上传图片):1、领取token前操作说明:在前台点击按钮上传图片前,需要先获取七牛云token。所需流程如下:1.1前台打开本地图片时,需要获取本地图片的名称(赋值给下面的key生成token),然后发送给后台,后台分配文件名(此时建议操作重命名文件名)分配密钥【这里是SDKv6生成token的方式】另一种方法是直接根据用户的公钥和私钥生成token,没有文件名的参与,在用户点击选择图片时在后台发送给前台。1.2后台根据:你的七牛云namespace的key和名字:bucket生成token发送给前台2.收到token后的操作2.1前台需要将文件转成字节流并然后将【token】和【文件字节流】和【文件名:key】打包成对象,然后开始发送到七牛云3.具体代码:后台运行//需要填写你的AccessKey和Secretkey这是在七牛云个人中心>密钥管理功能,qiniu.conf.ACCESS_KEY='0kSEeVVtcqWFQ18z0TWlDe6eBC3lFchpHLBNe-_F';//公钥qiniu.conf.SECRET_KEY='Y2P5am6LWW44yxo2YWwsiY4RteqyFeut58gCHBM_uck';//待上传私钥/et';//我的bucket名称,即文件的命名空间名称//上传到七牛后保存的文件名key='my-nodejs-logo.png';//这里我直接生成我需要的在前台保存的文件名,然后发送到后台。也可以直接把文件名发给后台,让后台处理。由于前后端是我一个人写的,比较随意//构建一个上传策略函数,生成token并设置回调url,需要回调业务服务器数据。这里的回调服务器地址需要你的公网服务器地址,但是我是直接在本地操作,没有公网地址,所以我没有改七牛云的例子,只是copyfunctionuptoken(bucket,key){varputPolicy=newqiniu.rs.PutPolicy(bucket+":"+key);putPolicy.callbackUrl='http://your.domain.com/callback';putPolicy.callbackBody='filename=$(fname)&filesize=$(fsize)';returnputPolicy.token();}//生成上传Tokentoken=uptoken(bucket,key);//这里的token需要发送给前台,这样前台才能开始操作上传图片console.log("七牛云上传图片token:",token);//后台代码结束前台操作//1.选择图像后,将文件名发送到背景中,以便背景可以生成tokenthis.axios.get('/filename','my-nodejs-logo.png')//filepath_or_or_or_stream是要上传的文件的本地路径或者字节流,虽然七牛云官方文档说最简单的//upload就是在本地上传的时候给一个本地路径//但是我觉得直接指定本地图片路径只是适用于后台上传,不适用于前台。具体原因见下文下一章//所以本文演示的都是文件数据,不是文件地址//filePath_or_stream='./nodejs-logo.png'||filePath_or_stream=readableStream【readableStream是所有文件的数据流前台传过来]filePath_or_stream=readableStream;//图片的字节流数据//2.选择图片后,开始上传前:gettokenthis.axios.get('/up/token').then(res=>{console.log(res)constformdata=newFormData()//FormData是浏览器html添加表单键值的方法可以,详细使用方法可以参考MDN文档。简单的介绍,看看我下面的介绍。文件reqreq.file是我们本地的文件地址。elementui的el-upload中的http-request就像我们本地电脑发起请求数据,会将我们选择的文件地址赋值给req.file(原生html表单上传属性也可以获取文件地址)formdata.append('token',res.data)//在表单上传的data字段追加token属性,其值为res.data,res.data是我们请求token数据时后台发送的formdata.append('key',keyname)//在表单上传的数据字段中添加key属性,keyname是我们需要保存的文件名custom//3.点击上传时:获取证书后,将文件上传到七牛cloudspace//this.domain是你要上传的七牛云空间绑定的域名,formdata包含所有上传的数据,config用于设置请求头this.axios.post(this.domain,formdata,config).then(res=>{this.imageUrl='http://'+this.qiniuaddr+'/'+res.data.key//console.log(this.imageUrl)})})方法二:上传图片的思路(通过后台上传图片):1.收到token前的操作说明:前台点击上传图片按钮时,【需要发送本地图片的名称和字节流数据】图片先传到后台],[或者修改后将修改后的图片名称和图片字节流数据发送到后台,需要的流程如下:1.1前台上传本地图片时,需要获取图片名称本地图片(用来赋值给后面的key,为了生成token),然后同时把图片字节流发给后台,后台赋值文件名(建议操作重命名此时的文件名)到key1.2。后台根据:key和你的七牛云命名空间名称为:bucket生成token另一种方法是直接根据用户的公私钥生成token,不需要文件名的参与2.收到token后的操作2.1后台生成token后,把[token]和[Filebytestream]和[Filename:key]打包成一个对象,然后开始发送给七牛云3.具体代码:后台操作//需要填写你的AccessKey和SecretKey在七牛云个人中心>KeyManagementFunctionqiniu.conf.ACCESS_KEY='0kSEeVVtcqWFQ18z0TWlDe6eBC3lFchpHLBNe-_F';//公钥qiniu.conf.SECRET_KEY='Y2P5am6LWW44yxo2YWCHwsiY4RteqyMut58'/webeuploadedSpace=bucketto-teach';//我的bucket名称,即文件的命名空间名称//上传到七牛后保存的文件名key='my-nodejs-logo.png';//这里我直接生成前台需要保存的文件名,然后发送给后端。也可以直接把文件名传给后端,让后端处理。由于前后端都是我写的,所以我比较随意//构造上传策略函数,生成token并设置回调url和需要回调给业务服务器的数据。这里的回调服务器地址需要你的公网服务器地址,//但是我是直接在本地操作,没有公网地址,所以我没有改七牛云的例子,直接copy不改functionuptoken(bucket,key){varputPolicy=newqiniu.rs.PutPolicy(bucket+":"+key);putPolicy.callbackUrl='http://your.domain.com/callback';putPolicy.callbackBody='filename=$(fname)&filesize=$(fsize)';returnputPolicy.token();}//生成上传TokenToken=uptoken(bucket,key);//这里的token需要根据【前台发来的图片名称】,即:[key]加上到[bucket]生成console.log("七牛云上传图片token:",token);//filePath_or_stream是要上传文件的本地路径或者字节流,虽然七牛云官方文档说最简单//上传是在本地上传的时候给个本地路径。//但是我觉得直接指定本地图片路径只适合后台上传,不适合前台。所有文件数据,不是文件地址//filePath_or_stream='./nodejs-logo.png'||filePath_or_stream=readableStream[readableStream是前台传过来的所有文件的数据流]filePath_or_stream=readableStream;//用传过来的前台分配字节流数据//构造上传函数uptoken:上传凭证,由bucket和我们传过来的[key是要保存的文件名]生成。key[key是要保存的文件名],//localFile[本地文件,可以是数据流也可以是地址,本文使用数据流]functionuploadFile(uptoken,key,localFile){varextra=新七牛.PutExtra();qiniu.io.putFile(uptoken,key,localFile,extra,function(err,ret){if(!err){//上传成功,处理返回值console.log(ret.hash,ret.key,ret.persistentId);}else{//上传失败,处理返回码console.log(err);}});}//调用uploadFile上传uploadFile(token,key,filePath_or_stream);前台操作就不写了,idea本文主要介绍的思路。2.代码文章由于代码比较多,我直接上传了gitee。可以直接从我的gitee下载源码,直接运行即可:我的:gitee写了三个小demo,分发使用:1.使用elementUI的上传组件实现上传图片;2.使用原h5input元素的file属性上传图片;3.使用vue-cropper实现图片上传前裁剪。三、后记1、关于filePath_or_stream虽然七牛云允许我们在上传的时候直接上传本地图片的地址,但是我觉得这种场景只适合后台上传,后台上传还是有限制的。为什么?羊毛布?解释如下:因为我们在上传数据的时候,可以无缘无故的上传,需要点对点的数据传输。1.1场景模拟:(A向B发送数据,只发送数据的地址,相当于只发送图片的地址)假设A向B发送数据,那么A发送前必须拿到手上的数据给B。虽然这里有胡说八道的嫌疑,但确实有道理。假设我们上传图片的时候,前台直接把我们图片的地址发给七牛云,那么七牛云只收到我们本地电脑的地址,比如:localhost://we-teach/1.png那么虽然七牛云知道我们需要上传的图片地址,但我们无能为力。首先我们本地电脑的ip地址不是公网地址。即使七牛云知道我们本地的文件存储地址,也无法从我们的电脑上获取数据。如果是后台发送,需要后台部署在公网IP的服务器上。这个时候把地址发给七牛云,他收到请求后就可以从我们的服务器拉取数据了。当然,这些只是我的猜测,因为我对具体的技术不了解,而且还是菜鸟。1.2场景模拟:(A向B发送数据,发送数据的所有信息,相当于发送所有的图片)所以我想既然不懂只发送地址的原理,那就发送所有的data就是这样,原理简单易懂,A把所有的数据都拿过来,发到B的门口,那么B一定会拿到。所以本文中传递的数据都是图片的信息,而不仅仅是本地地址。1.3当前台只传输本地地址时,七牛云是否也能知道我们发送的图片的具体信息?这个可以用FormData对象,这个是浏览器的接口,原生js没有,也就是说这个方法只能用于html页面formData,就像它的名字,表单数据一样,可以用添加键值对以形成数据。具体用法可以参考MDN文档:https://developer.mozilla.org...FormData是一个构造函数,使用它需要新建一个实例constformdata=newFormData(),然后传入我们本地的图片地址:formdata.append('file',req.file),那么表单数据对象多了一个file属性,它的值为req.file。无论是使用elementUi上传组件还是原来的html上传元素,道理都是一样的,都可以使用formData。其实formData不只是传地址上传图片。当它附加一个表单对象时,它会自动注入表单对象的所有数据。比如formdata.append('file',req.file),它会将req.file的所有数据,也就是所有的图片数据,注入到名为file的属性值中。所以formData的本质就是注入一个form对象的所有数据。毕竟这不是传递本地文件的地址,而是将本地文件的所有数据流注入到表单中。小演示:.upload{width:600px;margin:0auto;}.avatar-uploader.el-upload{border:5pxdashed#ca1717!important;边界半径:6px;游标:指针;位置:相对;overflow:hidden;}.avatar-uploader.el-upload:hover{border-color:#409EFF;}.avatar-uploader-icon{font-size:28px;颜色:#8c939d;宽度:178px;高度:178px;行高:178px;178像素;高度:178px;display:block;}2.关于qiniu.io.PutExtra()varextra=newqiniu.io.PutExtra();//extra的官方文档中虽然没有明确说明,但是有例子,我猜是用来设置参数的可选值示例:个人认为当设置扩展参数,然后执行回调操作时,会将我们自定义的参数添加到七牛云原本返回的原始json数据响应中varputExtra=newqiniu.resume_up.PutExtra();//扩展参数putExtra.params={"x:name":"","x:age":27,}putExtra.fname='testfile.mp4';