【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 ...
随机推荐
- div拖拽移动事件
<style> * { margin: 0; padding: 0; } body { ...
- SpringBoot系列(二) 环境搭建,创建我的第一个程序HelloWord。
环境准备: jdk1.8:java version "1.8.0_231",详见链接 maven3.x:maven3.3以上版本,详见链接 IDEA2021:IntelliJ ID ...
- C#窗体内控件大小随窗体等比例变化
一.首先定义全局变量 1 private float X;//当前窗体的宽度 2 private float Y;//当前窗体的高度 3 private bool IsFirst = true; 二. ...
- chrome edge CORS 允许跨域
edge: edge://flags/#block-insecure-private-network-requests chrome: 在谷歌浏览器地址栏输入"chrome://flags/ ...
- Go版RuoYi
RuoYi-Go https://github.com/Kun-GitHub/RuoYi-Go 1. 关于我 个人介绍 2. 介绍 后端用Go写的RuoYi权限管理系统 (功能正在持续实现)后端 G ...
- 🌟 简单理解 React 的 createContext 和 Provider 🚀
在 React 应用中,我们经常需要在组件之间共享状态和数据.而 React 的 createContext 和 Provider 就是为了解决这个问题而诞生的. createContext:创建自定 ...
- wpfui:一个开源免费具有现代化设计趋势的WPF控件库
wpfui介绍 wpfui是一款开源免费(MIT协议)具有现代化设计趋势的WPF界面库.wpfui为wpf的界面开发提供了流畅的体验,提供了一个简单的方法,让使用WPF编写的应用程序跟上现代设计趋势. ...
- 面试官:谈谈对SpringAI的理解?
Spring AI 已经发布了好长时间了,目前已经更新到 1.0 版本了,所以身为 Java 程序员的你,如果还对 Spring AI 一点都不了解的话,那就有点太落伍了. 言归正传,那什么是 Spr ...
- Pycharm或cmd在Terminal中运行tensorboard、pip等python包
这个主要是添加python包的路径到环境变量里 因为装了anaconda,所以我们要找的是对应虚拟环境里的包路径,一般是放在anaconda安装路径下的anaconda3\envs\环境名\Scrip ...
- Grab 基于 Apache Hudi 实现近乎实时的数据分析
介绍 在数据处理领域,数据分析师在数据湖上运行其即席查询.数据湖充当分析和生产环境之间的接口,可防止下游查询影响上游数据引入管道.为了确保数据湖中的数据处理效率,选择合适的存储格式至关重要. Vani ...