问题原因

一般文件上传前端甚至可以不涉及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. linux系统下,安装docker教程,以CentOS8为例

    查看本机的系统信息: 使用命令 lsb_release -a ,可以看到本机是CentOS系统,版本是8.4.2105 一.安装docker 1.Docker的安装要求CentOS系统内核版本要高于3 ...

  2. C++常用模板

    常用模板: 数学: 1. 组合数 组合数 #include<bits/stdc++.h> using namespace std; #define ll long long const l ...

  3. 使用命令行(powershell)压缩(7Z RAR)指定日期文件

    使用命令行(powershell)压缩(7Z RAR)指定日期文件,powershell ,7z. WINDOWS命令行是无法按时间过滤文件的,我们通过powershell 里的Get-ChildIt ...

  4. k8s搭建安装 Harbor 私有镜像仓库(本地仓库,内网仓库)

    主要参考 https://www.cnblogs.com/wangzy-Zj/p/14011228.html 额外: 1.如果 harbor.yml中的域名和openssl 生成的不一致,你改了hos ...

  5. spark读取hive表,org.apache.spark.sql.AnalysisException: Unsupported data source type for direct query on files: hive;

    异常出现:spark读取hive表时,spark.read.table(hive.test) hdp版本的spark默认的catalog是spark,配置项 metastore.catalog.def ...

  6. MATLAB神经网络工具箱使用介绍

      本文介绍MATLAB软件中神经网络拟合(Neural Net Fitting)工具箱的具体使用方法.   在MATLAB人工神经网络ANN代码这篇文章中,我们介绍了MATLAB软件中神经网络(AN ...

  7. Abp vNext 模块化系统简单介绍

    怎么使用模块1. 建立模块直接的依赖关系,可以通过DependsOnAttribute特性来确定依赖关系2. 先配置模块,实现为模块填充数据和功能设置.3. 使用模块提供的功能接口 怎么定义模块1. ...

  8. Android 编译系统 defconfig文件的确定

    Android 编译系统 defconfig文件的确定 背景 经常在驱动改动的时候,同时改动2个文件,才知道他们分别对应不同的编译结果. 路径 对应版本 kernel/msm-4.4/arch/arm ...

  9. MFC基于对画框工程笔记->更改窗口图标以及生成的.exe图标

    一.前言 继前一篇生成MFC基于对话框工程->新建MFC对话框后,开始改动对话框图标以及生成的.exe图标. 原对话框图标以及.exe图标: 在菜单栏中选择生成目录为Release 打开Rele ...

  10. SpringBoot排查自动装配、Bean、Component、Configuration配置类

    排除自动装配AutoConfiguration @SpringBootApplication( exclude = { DataSourceAutoConfiguration.class, Mybat ...