【JavaScript】文件上传下载问题
问题原因
一般文件上传前端甚至可以不涉及JS来实现
input标签套在form标签,由form标签直接发送请求就可以实现上传功能
但是现在很多项目都使用前后端分离,AJAX一刀切所有。
input标签没有form表单标签支持,文件上传也要走AJAX完成
两种实现方案
1、基于FormData实现,利用JS封装成FormData参数来请求
2、利用JS的FileReader转码成Base64字符串参数来请求
关于Input中的File对象
https://blog.csdn.net/weixin_30617797/article/details/95833917
怎么获取到文件本身在JS中是被屏蔽的
但是能够提供一些基本信息:
1、文件名称 name
2、文件大小 size 以字节计算
3、文件类型 type
项目中的方案:
文件上传的标签是需要动态添加的
// 添加附件
$addAttachment.on('click', function() {
let imgLimit = 6;
if ($('#attachment').children().length == imgLimit) {
mui.alert("超过PDI上传限制!(" + imgLimit + ")");
return;
}
let inputHtmlCode = '';
inputHtmlCode += '<div style="display: flex; justify-content: space-between;padding:5px;margin-top:5px;overflow: scroll;">';
inputHtmlCode += ' <button type="button" func="del" class="mui-btn mui-btn-red delItem" style="display: block;">删除</button> ';
inputHtmlCode += ' <input type="file" style="box-sizing: border-box;">';
inputHtmlCode += '</div>';
$('#attachment').append(inputHtmlCode);
});
删除文件就直接移除DOM
// 删除附件
$('#attachment').on('click','.delItem', function() {
// $(this).parent().remove();
let $thisObj = $(this);
mui.confirm(
'是否取消此文件上传?',
'取消上传',
["否", "是"],
function (btnArr) {
if (btnArr.index == 1) $thisObj.parent().remove();
}
);
});
对上传的文件设置大小限制:
清空value属性即重置了文件选择
// 监听附件大小控制
$('#attachment').on('change','[type="file"]', function(event) {
let selectedFile = event.target.files[0];
let maxSizeLimit = 1024 * 1024 * 60; // 60m
if (selectedFile.size > maxSizeLimit) {
mui.alert('超过60M文件大小限制!');
this.value = '';
} // console.log('文件大小/字节:' + f.size);
// console.log('文件名称:' + f.name);
// console.log('文件类型:' + f.type);
});
新需求,不允许重复上传:
// 监听附件大小控制 和文件相同限制
$('#attachment').on('change','[type="file"]', function(e) {
// mui.alert('监听触发');
let thisIndex = $(this).index();
let file = e.target.files[0];
let maxSizeLimit = 1024 * 1024 * 60; // 60m
if (file.size > maxSizeLimit) {
mui.alert('超过60M文件大小限制!');
file.value = '';
return;
}
var _self = this;
var fileList= document.getElementsByClassName("file");
if(fileList && fileList.length > 0){
for(var i = 0 ; i < fileList.length ; i++){
var x = fileList[i];
if(x.getAttribute("fileName") == file.name){
this.value = "";
return mui.alert("上传的文件名不能相同");
}
}
} if(e.target.files[0]){
this.setAttribute("fileName" , e.target.files[0].name);
this.setAttribute("class" , "file");
}
});
最后是提交请求:
1、要创建一个formData对象,把input标签的首个文件对象入参,
2、Key键是根据接口的要求来写的,一般默认叫【file】
3、然后AJAX的contentType类型要设置【multipart/form-data】
接口是单个文件上传,如果要多个文件,就遍历请求
后台是把文件送到文件服务器上,fastdfs, 然后会返回服务器存储地址和文件名称
再把这个路径送到常规后台写入数据库中
$('#testing').on('click', function() {
// 封装报告附件参数
$('[type="file"]').each(function(index, element){
if (element.value != '') {
let thisFile = element.files[0];
let formData = new FormData();
formData.append("dmsFile", thisFile);
$.ajax({
url : dms.getServerIp() + dms.getDmsPath()["dcsfactorybase"] + "factoryBase/fdfsfile/upload" ,
data: formData,
async: false,
dataType: 'json', //服务器返回json格式数据
contentType: 'multipart/form-data',
type: 'POST', //HTTP请求类型
timeout: 30000, //超时时间设置为30秒;
contentType: false,
processData: false,
headers:{ 'jwt': localStorage.getItem("urlToken") },
success: function(res) {
console.log("执行请求成功 url: " + dms.getServerIp() + dms.getDmsPath()["appiJmc"] + "/licensePlate");
},
error: function(xhr, type, errorThrown) {
// console.log("执行请求失败 url: " + dms.getServerIp() + dms.getDmsPath()["appiJmc"] + "/licensePlate");
}
});
}
});
});
BASE64转码方案:
首先还是要选中到file文件对象
创建JS的一个文件读取对象
readAsDataUrl方法能够在文件对象中读取文件内容
然后重写onloaded方法,result就是文件的bas64编码
let selectedFile = event.target.files[0];
// let fileReader = new FileReader();
// fileReader.readAsDataURL(selectedFile);
// fileReader.onloadend = function (e) {
// console.log('文件编码 ->' + e.target.result);
// }
AJAX请求头还需要设置:
"Content-Type": "application/x-www-form-urlencoded"
文件下载:
一般后台接口返回的是一个响应的文件流对象
这个时候不要再用AJAX处理了,交给浏览器跳转解析就能实现
这会导致一些问题:
1、接口必须是GET请求
2、参数必须在地址中
在项目中的下载案例:
这里接口还而外要求提供JWT令牌才能进行下载,
否则下载失败
$('#attachment').on('click', '[type="button"]', function() {
let thisJqDom = $(this);
mui.confirm(
'是否要下载?\n【' + thisJqDom.text() + '】',
'下载文件',
["否", "是"],
function(btnList) {
if (btnList.index != 1) return;
let jwt = localStorage.getItem("urlToken");
window.location.href = dms.getServerIp() + dms.getDmsPath()["dcsfactorybase"] + "factoryBase/fdfsfile/downfilebykey" + '?key=' + thisJqDom.attr('link') + '&fileName=' + thisJqDom.text() + '&jwt=' + jwt;
}
);
});
【JavaScript】文件上传下载问题的更多相关文章
- SpringMVC文件上传下载
在Spring MVC的基础框架搭建起来后,我们测试了spring mvc中的返回值类型,如果你还没有搭建好springmvc的架构请参考博文->http://www.cnblogs.com/q ...
- 【精心推荐】几款极好的 JavaScript 文件上传插件
文件上传功能作为网页重要的组成部分,几乎无处不在,从简单的单个文件上传到复杂的批量上传.拖放上传,需要开发者花费大量的时间和精力去处理,以期实现好用的上传功能.这篇文章向大家推荐几款很棒的 JavaS ...
- WEB文件上传下载功能
WEB文件上传下载在日常工作中经常用到的功能 这里用到JS库 http://files.cnblogs.com/meilibao/ajaxupload.3.5.js 上传代码段(HTML) <% ...
- 2013第38周日Java文件上传下载收集思考
2013第38周日Java文件上传&下载收集思考 感觉文件上传及下载操作很常用,之前简单搜集过一些东西,没有及时学习总结,现在基本没啥印象了,今天就再次学习下,记录下自己目前知识背景下对该类问 ...
- Struts2实现文件上传下载功能(批量上传)
今天来发布一个使用Struts2上传下载的项目, struts2为文件上传下载提供了好的实现机制, 首先,可以先看一下我的项目截图 关于需要使用的jar包,需要用到commons-fileupload ...
- Java实现FTP批量大文件上传下载篇1
本文介绍了在Java中,如何使用Java现有的可用的库来编写FTP客户端代码,并开发成Applet控件,做成基于Web的批量.大文件的上传下载控件.文章在比较了一系列FTP客户库的基础上,就其中一个比 ...
- JavaWeb 文件上传下载
1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端,从服务器端下载文件到本地的过程.例如目前网站需要上传头像.上传下载图片或网盘等功能都是利用文件上传下 ...
- JavaWeb -- 文件上传下载示例
1. 上传简单示例 Jsp <%@ page language="java" import="java.util.*" pageEncoding=&quo ...
- SpringMVC ajax技术无刷新文件上传下载删除示例
参考 Spring MVC中上传文件实例 SpringMVC结合ajaxfileupload.js实现ajax无刷新文件上传 Spring MVC 文件上传下载 (FileOperateUtil.ja ...
- django 12天(跨域,文件上传,下载,cookie,session)
django 12天(跨域,文件上传,下载) 跨域 什么是跨域 1.协议不同 2.端口不同 3.主机不同 如何解决跨域 1.安装django-cors-headers模块 2.在settings.py ...
随机推荐
- echarts做折线图
先给大家看图 父组件 <el-container v-show="abscissa"> <lineEchart :C ...
- 状态管理(redux)
https://www.redux.org.cn/ 2013年 Facebook 提出了 Flux 架构的思想,引发了很多的实现.2015年,Redux 出现,将 Flux 与函数式编程结合一起,很短 ...
- vue饼图
结果图 原型 1 <template> 2 <!-- 左右柱状图 --> 3 <div ref="rankEcharts" :style=" ...
- echo输出带颜色的字
文章目录 格式 所有颜色 字体样式 示例 格式 \033[A;F;Bm #放在文本的左边,可以影响后面所有字体的样式 解释: F代表字体颜色值(Font),颜色编号30~37. B代表背景颜色值(Ba ...
- 05-CentOS防火墙
概述 CentOS中的防火墙有很多,如SELinux.Firewall.TCP Wrappers.iptables/netfilter. 每种防火墙都有各自擅长的地方. 这里主要讲两种:SELinux ...
- 了解Microsoft Media Foundation
关于Microsoft Media Foundation 是什么 Microsoft Media Foundation是用来处理(创建.修改.传输.合成)多媒体数据(音视频)的一个平台. 有什么用 M ...
- mtr和traceroute的区别,以及为什么traceroute不显示路径mtr却可以显示路径
最近工作主要都是网络策略的开通和网络测试,在测试的过程当中发现当网络不通时,用traceroute来看路由路径的时候总是无法显示出来,于是就换了个工具-mtr,发现mtr可以正常显示出路由路径,帮助我 ...
- 机器学习(四)——Lasso线性回归预测构建分类模型(matlab)
Lasso线性回归(Least Absolute Shrinkage and Selection Operator)是一种能够进行特征选择和正则化的线性回归方法.其重要的思想是L1正则化:其基本原理为 ...
- linux 4.19 ip重组
IP重组 ip重组这部分 4.19内核与3.10内核有些差别,4.9.134以后内核中不使用低水位和工作队列了,同时使用了rhashtable 替代了 hash bucket的概念,在3.10内核中使 ...
- 两张图带你全面了解React状态管理库:zustand和jotai
zustand 和 jotai 是当下比较流行的react状态管理库.其都有着轻量.方便使用,和react hooks能够很好的搭配,并且性能方面,对比React自身提供的context要好得多,因此 ...