问题原因

一般文件上传前端甚至可以不涉及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】文件上传下载问题的更多相关文章

  1. SpringMVC文件上传下载

    在Spring MVC的基础框架搭建起来后,我们测试了spring mvc中的返回值类型,如果你还没有搭建好springmvc的架构请参考博文->http://www.cnblogs.com/q ...

  2. 【精心推荐】几款极好的 JavaScript 文件上传插件

    文件上传功能作为网页重要的组成部分,几乎无处不在,从简单的单个文件上传到复杂的批量上传.拖放上传,需要开发者花费大量的时间和精力去处理,以期实现好用的上传功能.这篇文章向大家推荐几款很棒的 JavaS ...

  3. WEB文件上传下载功能

    WEB文件上传下载在日常工作中经常用到的功能 这里用到JS库 http://files.cnblogs.com/meilibao/ajaxupload.3.5.js 上传代码段(HTML) <% ...

  4. 2013第38周日Java文件上传下载收集思考

    2013第38周日Java文件上传&下载收集思考 感觉文件上传及下载操作很常用,之前简单搜集过一些东西,没有及时学习总结,现在基本没啥印象了,今天就再次学习下,记录下自己目前知识背景下对该类问 ...

  5. Struts2实现文件上传下载功能(批量上传)

    今天来发布一个使用Struts2上传下载的项目, struts2为文件上传下载提供了好的实现机制, 首先,可以先看一下我的项目截图 关于需要使用的jar包,需要用到commons-fileupload ...

  6. Java实现FTP批量大文件上传下载篇1

    本文介绍了在Java中,如何使用Java现有的可用的库来编写FTP客户端代码,并开发成Applet控件,做成基于Web的批量.大文件的上传下载控件.文章在比较了一系列FTP客户库的基础上,就其中一个比 ...

  7. JavaWeb 文件上传下载

    1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端,从服务器端下载文件到本地的过程.例如目前网站需要上传头像.上传下载图片或网盘等功能都是利用文件上传下 ...

  8. JavaWeb -- 文件上传下载示例

    1. 上传简单示例 Jsp <%@ page language="java" import="java.util.*" pageEncoding=&quo ...

  9. SpringMVC ajax技术无刷新文件上传下载删除示例

    参考 Spring MVC中上传文件实例 SpringMVC结合ajaxfileupload.js实现ajax无刷新文件上传 Spring MVC 文件上传下载 (FileOperateUtil.ja ...

  10. django 12天(跨域,文件上传,下载,cookie,session)

    django 12天(跨域,文件上传,下载) 跨域 什么是跨域 1.协议不同 2.端口不同 3.主机不同 如何解决跨域 1.安装django-cors-headers模块 2.在settings.py ...

随机推荐

  1. CF1836

    A.Destroyer 开个桶记录个数,看满不满足单调不上升即可. B.Astrophysicists 辛辛苦苦写了这么久的文章就没了????烦死了. 自己做 Virtual Contest 的时候这 ...

  2. linux系统,kafka常用命令

    kafka版本过高所致,2.2+=的版本,已经不需要依赖zookeeper来查看/创建topic,新版本使用 --bootstrap-server替换老版本的 --zookeeper-server. ...

  3. .net执行oracle查询语句报错“指定的转换无效”解决方案

    问题: .net执行oracle查询语句报错"指定的转换无效",在PL/SQL中正常: SELECT A.ID,SUM(TO_NUMBER(A.MODIFYTIME-A.UPLOA ...

  4. star 最多的 Go 语言本地化库|GitHub 2.8K

    如果你是一位 Go 用户,可以在我开源的学习仓库中,找到针对各种往期归档文章,及学习资料. B站:白泽talk,公众号[白泽talk],回复"电子书",即可获得包含<100个 ...

  5. idea编译报错 Lombok运行测试类报错 jar依赖冲突解决

    idea编译报错 Lombok运行测试类报错 jar依赖冲突解决 1.现象是idea编译,运行项目的时候是没有问题,可以正常跑起来.2.运行junit测试类的时候,报错提示 lombok找不到类,解决 ...

  6. 超越datetime:Arrow,Python中的日期时间管理大师

    介绍 Arrow是一个Python库,它提供了一种合理且对人类友好的方法来创建.操作.格式化和转换日期.时间和时间戳.它实现了对datetime类型的更新,填补了功能上的空白,提供了一个智能的模块AP ...

  7. Java面试知识点(五)hashmap、hashtable和hashset

    1. 关于 HashMap 的一些说法: a) HashMap 实际上是一个 "链表散列" 的数据结构,即数组和链表的结合体.HashMap 的底层结构是一个数组,数组中的每一项是 ...

  8. invalid comparison: java.util.Date and java.lang.String异常的原因

    mybatis查询时使用date类型与""比较导致的 例 <if test="params.applicationEndTime != null and param ...

  9. python重拾第八天-Socket网络编程

    本节内容 Socket介绍 Socket参数介绍 基本Socket实例 Socket实现多连接处理 通过Socket实现简单SSH 通过Socket实现文件传送 作业:开发一个支持多用户在线的FTP程 ...

  10. 总结:软件开发的3个方向 与 嵌入式Linux学习路线(驱动方向)

    --- title: 嵌入式Linux学习路线图(驱动方向) date: 2020-05-09 07:17:58 categories: tags: - embeded - summary - arm ...