问题原因

一般文件上传前端甚至可以不涉及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. 【Java面试题-基础知识02】Java抽象类和接口六连问?

    1.抽象类和接口分别是什么? 抽象类是一种类,可以包含抽象方法和非抽象方法,抽象方法是没有具体实现的方法,需要在子类中被具体实现. 接口是一种完全抽象的类,其中的所有方法都是抽象方法,没有方法体,它只 ...

  2. python解析字符串中的省市区字符串

    #python解析字符串中的省市区字符串 #str4 = "XX省XX市辛桥乡赵庄村XX号" #str4 = "XX省XX市XX区八卦二路XX号XX栋XX楼" ...

  3. oracle数据库与oracle实例

    1 oracle数据库分类 1.1 单租户数据库 ORACLE12C之前的oracle数据库都是单租户数据库.单租户数据库是独立和完整的数据库,包括ORACLE的元数据和应用的数据. 1.2 容器数据 ...

  4. emlog新浪上传插件+接口 V1.1

    Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` emlog新浪上传插件+接口 V1.1 日期:2018-4 ...

  5. 支付宝 返回的form如何在前端打开

    支付宝支付时返回了一段标签标签大概是 <form></form><script></script> 试了innerHtml怎么试都不能用,是那种直接把字 ...

  6. Libgdx游戏开发(5)——碰撞反弹的简单实践

    原文: Libgdx游戏开发(5)--碰撞反弹的简单实践-Stars-One的杂货小窝 本篇简单以一个小球运动,一步步实现碰撞反弹的效果 本文代码示例以kotlin为主,且需要有一定的Libgdx入门 ...

  7. 十大java应用服务器(web server)总结

    java应用服务器(web server),是指运行java程序的web应用服务器软件,不包括nginx.Apache等通用web服务器软件. 一.Tomcat Tomcat是Apache 软件基金会 ...

  8. MySQL日志(redo log、binlog)刷盘策略

    通过上篇文章,我们知道MySQL是采用两段提交策略来保证事务的原子性的,redo log刷盘的时机是在事务提交的commit阶段采取刷盘的,在此之前,redo log都存在于redo log buff ...

  9. Windows下Qt5程序打包发布

    Windows下Qt5程序打包发布与图标设置 原文(有删改):https://blog.csdn.net/qq_39105333/article/details/114779650 设置程序图标 默认 ...

  10. 关于ZYNQ-7000中断调试一点感想

    背景 在ZYNQ 平台下,需要对各种需要的底层接口进行初始化. 我依次调试了很多驱动,从最简单的网口到USB:再到读写PL端的寄存器(通过AXI总线,内存映射读写物理地址实现),到中断的时候一直卡着不 ...