@[toc]关于文件上传,宋哥之前写过好几篇文章,甚至还有一个视频:SpringBoot+Vue+FastDFS实现前后端分离的文件上传。不过之前跟朋友提过方案是基于session进行认证的,所以不需要考虑携带token的问题,但是在前后端分离的开发中,我们可能会使用JWT或者OAuth2+JWT进行身份验证。如果是这样,那么我们必须手动传递令牌。今天跟大家聊聊手动传递token。1、我们先看看传统的方案,如何基于session认证上传文件。在Vue.js中,如果网络请求使用axios,使用ElementUI库,一般来说文件上传有两种不同的实现方案:通过Ajax上传文件和通过ElementUI中的Upload组件上传文件,各有优缺点,我们分开来看。1.1准备工作首先我们需要做一点准备工作,就是在后台提供一个文件上传接口。这是一个普通的SpringBoot工程,如下:SimpleDateFormatsdf=newSimpleDateFormat("/yyyy/MM/dd/");@PostMapping("/import")publicRespBeanimportData(MultipartFilefile,HttpServletRequestreq)throwsIOException{Stringformat=sdf.format(新日期());StringrealPath=req.getServletContext().getRealPath("/upload")+格式;文件夹=新文件(realPath);如果(!folder.exists()){folder.mkdirs();}StringoldName=file.getOriginalFilename();StringnewName=UUID.randomUUID().toString()+oldName.substring(oldName.lastIndexOf("."));file.transferTo(新文件(文件夹,新名称));Stringurl=req.getScheme()+"://"+req.getServerName()+":"+req.getServerPort()+"/upload"+format+newName;System.out.println(url);returnRespBean.ok("Uploadedsuccessful!");}这里的文件上传比较简单,上传的文件是按照Dates排序并使用UUID重命名文件。这里为了简化代码,我省略了异常捕获,上传结果直接返回成功。大家可以根据自己的实际情况修改后台代码。这里为了方便,我直接把文件存到本地,小伙伴们也可以结合FastDFS来更专业的上传文件,可以参考松哥的这篇文章:SpringBoot+Vue+FastDFS实现前后端分离文件上传.1.2Ajax上传在Vue中,文件上传是通过Ajax实现的。该方案与传统Ajax实现文件上传的方案基本相同。唯一的区别是查找元素的方式。导入数据这里先提供一个导入input组件的文件,再提供一个导入按钮,在导入按钮的事件中完成导入逻辑。importData(){letmyfile=this.$refs.myfile;让files=myfile.files;让文件=文件[0];varformData=newFormData();formData.append("文件",文件);这。uploadFileRequest("/system/basic/jl/import",formData).then(resp=>{if(resp){console.log(resp);}})}这个上传的核心逻辑解释如下:首先在Vue中使用$refs查找保存文件的元素。类型为file的input元素内部有一个files数组,里面存储了所有选中的文件。由于上传文件时可以多次选择文件,所以这里获取的files对象是一个数组。从文件对象中,获取要上传的文件。由于这是一个单一的选择,它实际上是数组中的第一项。构造一个FormData来存储上传的数据。FormData不能像Java中的StringBuffer那样使用链式配置。FromData构造完成后,就可以直接上传数据了,FormData就是要上传的数据。上传文件要注意两点,1.请求方式为post,2.设置Content-Type为multipart/form-data。这种文件上传方式其实就是传统的Ajax上传文件。不同于常见的jQuery写法。这里的元素查找方式不同(其实元素查找也可以按照JavaScript中原来的写法来实现)。其他拼写完全??相同。该方法为通用方法,与使用何种前端框架无关。最后看一下打包后的上传方法:exportconstuploadFileRequest=(url,params)=>{returnaxios({method:'post',url:`${base}${url}`,data:params,headers:{'Content-Type':'multipart/form-data'}});}经过这几步的配置,即使前端上传完成,也可以上传文件了。1.3使用el-upload组件如果使用el-upload,需要引入ElementUI,所以一般建议如果使用ElementUI作为UI控件,可以考虑使用el-upload组件上传文件。如果不使用ElementUI,那么不推荐使用el-upload组件。至于其他UI控件,每个控件都有自己的文件上传组件。具体使用请参考各自的文档。{{btnText}}show-file-list表示是否显示上传的文件列表,默认为true,这里设置为不显示。before-upload表示上传前的回调。在这个方法中,可以做一些准备工作,比如给用户显示一个进度条。on-success和on-error分别表示上传成功和失败时的回调。您可以在这两种方法中给用户相应的提示。如果有进度条,需要在这两个方法中关闭进度条。action指的是文件上传地址。上传按钮的点击状态和图标设置为变量。文件上传过程中,修改上传按钮的点击状态为不可点击,修改图标为加载图标loading。上传的文本也被设置为一个变量。默认情况下,上传按钮的文本是DataImport。上传开始时,将按钮上的文本更改为导入。对应的回调如下:onSuccess(response,file,fileList){this.enabledUploadBtn=true;this.uploadBtnIcon='el-icon-upload2';this.btnText='dataimport';},onError(err,file,fileList){this.enabledUploadBtn=true;this.uploadBtnIcon='el-icon-upload2';this.btnText='数据导入';},beforeUpload(file){this.enabledUploadBtn=false;this.uploadBtnIcon='el-icon-loading';this.btnText='Importing';}当文件开始上传时,修改上传按钮不可点击,同时修改上传按钮的图标和文字。当文件上传成功或失败时,修改上传按钮的状态为可点击,并恢复上传按钮的图标和文字。上传效果图如下:使用el-upload上传文件。之前松哥也录了个视频,小伙伴们可以参考一下(这个视频摘自松哥制作的SpringBoot+Vue+微人事系列视频教程):1.4两种方式对比两种上传方式各有优缺点:第一种方式最大的优点是通用性强,可以在任何地方使用,但是对于上传过程的监控,进度条的显示等逻辑需要自己去实施。第二种方式不够通用,因为它是ElementUI中的组件,必须引入ElementUI才能使用。不过这种方式显然需要更方便的回调,可以很方便的处理各种常见的上传问题。第二种方式可以满足一般的上传需求,但是如果要自定义上传方式,建议使用第一种上传方式。2、手动传递token针对以上不同的文件上传方式,手动上传token也有不同的方案。宋哥一一为大家介绍。我这里的服务端认证是OAuth2+JWT,所以接下来的token传输主要是按照OAuth2格式传输token。其实就是修改请求头。只要这个方法行得通,其他的方法也会行得通。关于OAuth2,不熟悉的可以看看宋哥写的系列教程:OAuth2系列2.1Ajax传递令牌Ajax传递令牌其实很简单,我们只需要稍微修改请求头即可。让我给你一个简单的例子。如果使用axios进行网络请求,可以如下添加请求头(或者在请求拦截器中统一添加):exportconstuploadFileRequest=(url,params)=>{returnaxios({method:'post',url:`${base}${url}`,data:params,headers:{'Content-Type':'multipart/form-data','Authorization':'Bearer'+token}});}如果你使用jQuery,然后添加请求头如下:$("#btnClick").click(function(){varformData=newFormData();formData.append("file",$("#userface")[0].files[0]);$.ajax({url:'/fileupload',type:'post',headers:{'Authorization':'Bearer'+token},data:formData,processData:false,contentType:假,成功:功能(味精){警报(味精);}});});无非就是修改请求头,只要是自己发送请求,请求头都可以自由定制,不管你用的是jQuery还是axios还是原生的XMLHttpRequest。2.2el-uploadprocessingtoken如果使用el-upload,我们就得在别人的框架里玩,满足框架的要求。虽然有一些限制,但并非不可能实现。宋歌将介绍两种方案。2.2.1方案一方案一是我目前使用的方案,因为el-upload支持自定义请求头,好办:选择图标其中:headers="myHeaders"它是我自定义的requestheader,然后在data里定义变量:data(){return{myHeaders:{Authorization:'Bearer'+getToken()}}},2.2.2方案二方案二使用el-upload的before-uploadhook函数,开发者可以在这个hook函数中手动上传,上传完成后返回false,el-upload会停止自己的上传逻辑。我看到其他朋友用过这种方法,所以我给你一个简单的案例供你参考:beforeUpload(file){//参考上面的ajax或axios上传文件返回false}这里有几个需要注意的细节:el-upload的action属性可以随意赋值,这样它不会报错,因为真正的上传地址我们会在beforeUpload方法中给出。beforeUpload方法的上传逻辑和我们第一节介绍的一致,不再赘述。注意上传的文件对象是file.raw。beforeUpload方法最终返回false,终止el-upload自身的上传逻辑。3.总结完成。我在和朋友上传文件的时候介绍过几种token转账的方式。请问你有GET吗?如果您有任何问题,请留言讨论。有学到东西记得点开看给宋哥加油哦~