上传文件设置 formData
var formData = new FormData();formData.append("file", $("#postfile")[0].files[0]);
防止浏览器缓存页面或请求结果
public class NoCacheFilter implements Filter { @Override public void destroy(){ } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse)resp; response.setDateHeader("Expires", -1); response.setHeader("Cache_Control", "no-cache"); response.setHeader("Pragma", "no-cache"); response.setHeader("Access-Control-Allow-Origin", "*"); //允许跨域请求 chain.doFilter(req, resp); } @Override public void init(FilterConfig arg0) throws ServletException { } }

默认情况下,跨源请求不提供凭据(cookie、HTTP 认证及客户端SSL证明等)。通过将 withCredentials 属性设置为 true,可以指定某个请求应该发送凭据。如果服务器接收带凭据的请求,会用下面的 HTTP 头部来响应。

其实就是我们刚才设置的第二条配置。
虽然设置了 widthCredentials 为 true 的请求中会包含远程域的所有 cookie,但这些 cookie 仍然遵循同源策略,所以外域是访问不了这些 cookie 的,现在我们就可以安全地跨域访问了。
一、input:file 属性
属性值有以下几个比较常用:
- accept:表示可以选择的文件 MIME 类型,多个 MIME 类型用英文逗号分开,常用的 MIME 类型见下表。
- multiple:是否可以选择多个文件,多个文件时其value值为第一个文件的虚拟路径。
1、accept
只能选择 png 和 gif 图片
<input type="file" accept="image/png,image/gif" name="file" />
2、multiple
多文件上传
<input type="file" multiple="multiple" name="file" />
3、常用 MIME 类型
*.3gpp audio/3gpp, video/3gpp*.ac3 audio/ac3*.asf allpication/vnd.ms-asf*.au audio/basic*.css text/css*.csv text/csv*.doc application/msword *.dot application/msword *.dtd application/xml-dtd *.dwg image/vnd.dwg *.dxf image/vnd.dxf*.gif image/gif *.htm text/html *.html text/html *.jp2 image/jp2 *.jpe image/jpeg*.jpeg image/jpeg*.jpg image/jpeg *.js text/javascript, application/javascript *.json application/json *.mp2 audio/mpeg, video/mpeg *.mp3 audio/mpeg *.mp4 audio/mp4, video/mp4 *.mpeg video/mpeg *.mpg video/mpeg *.mpp application/vnd.ms-project *.ogg application/ogg, audio/ogg *.pdf application/pdf *.png image/png *.pot application/vnd.ms-powerpoint *.pps application/vnd.ms-powerpoint *.ppt application/vnd.ms-powerpoint *.rtf application/rtf, text/rtf *.svf image/vnd.svf *.tif image/tiff *.tiff image/tiff *.txt text/plain *.wdb application/vnd.ms-works *.wps application/vnd.ms-works *.xhtml application/xhtml+xml *.xlc application/vnd.ms-excel *.xlm application/vnd.ms-excel *.xls application/vnd.ms-excel *.xlt application/vnd.ms-excel *.xlw application/vnd.ms-excel *.xml text/xml, application/xml *.zip aplication/zip *.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
三、AJAX上传文件
在说到 ajax 上传文件,之前的文章也有说过。ajax 上传的时候,需要获得 input:file 选择的文件(可能为多个文件),获取其文件列表为:
// input标签的files属性document.querySelector("#fileId").files// 返回的是一个文件列表数组获得的文件列表,然后遍历插入到表单数据当中。即:// 获得上传文件DOM对象var oFiles = document.querySelector("#fileId");// 实例化一个表单数据对象var formData = new FormData();// 遍历图片文件列表,插入到表单数据中for (var i = 0, file; file = oFiles[i]; i++) { // 文件名称,文件对象 formData.append(file.name, file);}获得表单数据之后,就可以用ajax的POST上传。// 实例化一个AJAX对象var xhr = new XMLHttpRequest();xhr.onload = function() { alert("上传成功!");}xhr.open("POST", "upload.php", true);// 发送表单数据xhr.send(formData);
上传到服务器之后,获取到文件列表为:
Array([jpg_jpg] => Array ( [name] => jpg.jpg [type] => image/jpeg [tmp_name] => D:\xampp\tmp\phpA595.tmp [error] => 0 [size] => 133363 )[png_png] => Array ( [name] => png.png [type] => image/png [tmp_name] => D:\xampp\tmp\phpA5A6.tmp [error] => 0 [size] => 1214628 ))
在服务端循环遍历这个数组就可以上传文件了。
<input type="file" accept="text/plain" multiple="multiple" />function postFile() { //判断是否有选择上传文件 var imgPath = $("#postfile").val(); if(imgPath == "") { $(".poststate").text("请选择上传的文本文件,以.txt后缀结尾!").css("color", "blue"); return; } var strExtension = imgPath.substr(imgPath.lastIndexOf('.') + 1); //判断上传文件的后缀名 if(strExtension != 'txt') { $(".poststate").text("请选择上传的文本文件,以.txt后缀结尾!").css("color", "blue"); return; } var formData = new FormData(); formData.append("file", $("#postfile")[0].files[0]); console.log(postfile.files[0]); $.ajax({ contentType: "multipart/form-data", url: "s3/operationmsg/upload", type: "POST", data: formData, dataType: "text", processData: false, contentType: false, cache: false, beforeSend: function() { $(".poststate").text("正在努力上传中,请稍后!").css("color", "green"); }, success: function(data) { var reObj = JSON.parse(data); if(reObj.content) { $(".poststate").text('"' + reObj.content.fileName + '"' + "上传成功!").css("color", "green"); } }, error: function(XMLHttpRequest, textStatus, errorThrown) { $(".poststate").text("上传失败,请检查网络后重试!").css("color", "red");; } });}$("#postfile").on('change', function() { //文件上传 $(".poststate").text("请选择上传以.txt后缀结尾的文本文件!").css("color", "blue"); postFile();});var fileInfo =$('#inputfile').prop('files')[0];var fd = new FormData();fd.append("xxxx", fileInfo);$.ajax({ url: "xxxx.htm", type: "POST", processData: false, contentType: false, dataType: 'json', data: fd, success:function(data){}, error:function(data){}});
关于 JQuery 上传图片 input file change 事件只触发一次问题:
$(document).on('change onpropertychange',"#imgUrl", function() { //文件上传 var file = this.files[0]; console.log(file); if((file.size / 1024).toFixed(0)>300){ $.alert({ title: '提示!', content: "图片大小为:"+(file.size / 1024).toFixed(0)+"kb,要求不能大于300kb", confirm: function(){ } }); return; }; //读取图片数据 var reader = new FileReader(); reader.onload = function (e) { var data = e.target.result; //加载图片获取图片真实宽度和高度 var image = new Image(); image.onload=function(){ var width = image.width; var height = image.height; if(width=="590"&&height=="824"){ postFile(); $('#imgUrl').replaceWith('<input type="file" multiple="multiple">'); }else{ $.alert({ title: '提示!', content: "图片宽高不符合590*824!", confirm: function(){ } }); $('#imgUrl').replaceWith('<input type="file" multiple="multiple">'); } }; image.src= data; }; reader.readAsDataURL(file);});$(document).on('change onpropertychange', "#postfile",function() { //这里要用事件委派b $(".poststate").text("请选择上传以.txt后缀结尾的文本文件!").css("color", "blue");postFile();$('#postfile').replaceWith('<input type="file" accept="text/plain" multiple="multiple" />');});function postFile() { //判断是否有选择上传文件 var imgPath = $("#postfile").val(); if(imgPath == "") { $(".poststate").text("请选择上传的文本文件,以.txt后缀结尾!").css("color", "blue"); return; } var strExtension = imgPath.substr(imgPath.lastIndexOf('.') + 1); //判断上传文件的后缀名 if(strExtension != 'txt') { $(".poststate").text("请选择上传的文本文件,以.txt后缀结尾!").css("color", "blue"); return; } var formData = new FormData(); formData.append("file", $("#postfile")[0].files[0]); //console.log(postfile.files[0]); $.ajax({ contentType: "multipart/form-data", url: "xxxx/xxxxx/xx", type: "POST", data: formData, dataType: "text", processData: false, contentType: false, cache: false, beforeSend: function() { $(".poststate").text("正在努力上传中,请稍后!").css("color", "blue"); }, success: function(data) { var reObj = JSON.parse(data); if(reObj.status=="0"){ if(reObj.content) { $.alert({ title: '提示:', backgroundDismiss: true, content: '上传文件成功!' }); $(".poststate").text('"' + reObj.content.fileName + '"' + "上传成功!").css("color", "blue"); PostObj.pubS3FileUrl = reObj.content.url; }else { $.alert({ title: '提示:', backgroundDismiss: true, content: reObj.message }); $(".poststate").text(""); } }else{ PostObj.pubS3FileUrl=""; $.alert({ title: '提示:', backgroundDismiss: true, content: reObj.message }); $(".poststate").text(reObj.message); } }, error: function(XMLHttpRequest, textStatus, errorThrown) { $(".poststate").text("上传失败,请检查网络后重试!").css("color", "red");; } });}
用来把文件读入内存,并且读取文件中的数据。FileReader 接口提供了一个异步 API,使用该 API 可以在浏览器主线程中异步访问文件系统,读取文件中的数据。到目前文职,只有 FF3.6+ 和 Chrome6.0+ 实现了 FileReader 接口。
1、FileReader 接口的方法
FileReader 接口有4个方法,其中3个用来读取文件,另一个用来中断读取。无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result 属性中。
readAsBinaryStringfile 将文件读取为二进制编码
readAsTextfile,[encoding] 将文件读取为文本
readAsDataURLfile 将文件读取为 DataURL
abort(none) 终端读取操作
2、FileReader 接口事件
FileReader 接口包含了一套完整的事件模型,用于捕获读取文件时的状态。
onabort 中断
onerror 出错
onloadstart 开始
onprogress 正在读取
onload 成功读取
onloadend 读取完成,无论成功失败
上传图片预览:
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> * { padding: 0; margin: 0; } .container { width: 800px; margin: 100px auto; } .imgs { width: 300px; height: 300px; } .imgs img { width: 100%; } </style> </head> <body> <div> <input type="file" name="file" value="上传" /> <div> <img src="" /> </div> <div> <img src="" /> </div> <div> <img src="" /> </div> <div> <img src="" /> </div> </div> <script type="text/javascript"> var fe = document.getElementById("file"); var img = document.getElementById("preImg"); var img1 = document.getElementById("preImg1"); var img2 = document.getElementById("preImg2"); var img3 = document.getElementById("preImg3"); fe.onchange = function() { var reader = new FileReader(); var _file = this.files[0]; console.log("reader"); console.log(reader); // 建议去输出下这3个东西 仔细看看就明白了 console.log("this.files"); console.log(this.files); console.log("_file"); console.log(_file); reader.readAsDataURL(_file); //这个是很重要的一步 讲读取到的文件编码成DataURL 否则不能用 console.log("reader"); console.log(reader); reader.onload = function() { img.setAttribute('src', this.result); }; } </script> </body></html><!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script type="text/javascript"> var result = document.getElementById("result"); var file = document.getElementById("file"); //判断浏览器是否支持FileReader接口 if(typeof FileReader == 'undefined') { result.InnerHTML = "<p>你的浏览器不支持FileReader接口!</p>"; //使选择控件不可操作 file.setAttribute("disabled", "disabled"); } function readAsDataURL() { //检验是否为图像文件 var file = document.getElementById("file").files[0]; if(!/image\/\w+/.test(file.type)) { alert("看清楚,这个需要图片!"); return false; } var reader = new FileReader(); //将文件以Data URL形式读入页面 reader.readAsDataURL(file); reader.onload = function(e) { var result = document.getElementById("result"); //显示文件 result.innerHTML = '<img src="" alt="" />'; } } function readAsBinaryString() { var file = document.getElementById("file").files[0]; var reader = new FileReader(); //将文件以二进制形式读入页面 reader.readAsBinaryString(file); reader.onload = function(f) { var result = document.getElementById("result"); //显示文件 result.innerHTML = this.result; } } function readAsText() { var file = document.getElementById("file").files[0]; var reader = new FileReader(); //将文件以文本形式读入页面 reader.readAsText(file); reader.onload = function(f) { var result = document.getElementById("result"); //显示文件 result.innerHTML = this.result; } } </script> <p> <label>请选择一个文件:</label> <input type="file" /> <input type="button" value="读取图像" onclick="readAsDataURL()" /> <input type="button" value="读取二进制数据" onclick="readAsBinaryString()" /> <input type="button" value="读取文本文件" onclick="readAsText()" /> </p> <div name="result"></div> </body></html>
上传文件预览:

准备上传
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>文件上传</title> <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.2.0/css/bootstrap.min.css"> <script src=""></script> <style> body, html { margin: 0 auto; } .up-header { width: 600px; text-align: center; } .up-content { min-height: 200px; border: 1px solid #CCCCCC; display: flex; flex-direction: column; justify-content: center; align-items: center; background-color: #FAFAFA; color: #999; font-size: 20px; text-align: center; } .up-area { border: 2px dashed #ccc; margin: 10px 20px 20px 20px; width: 300px; min-height: 200px; line-height: 100px; background-color: #fff; } .list-group { margin: 0px auto; ; width: 200px; min-height: 100px; padding: 10px; } img { max-width: 100%; } .btn {} .close { margin-left: 550px; margin-top: -20px; } </style> </head> <body> <header> <!-- 头部显示 --> <div> <div> <h2>文件上传——两种形式</h2> <div style="width:600px; display:flex;"> <input type="text" placeholder="在此处粘贴图片网址"> <button type="button">上传图片</button> </div> </div> <div> <!-- 拖拽图片到这来 --> <div> <p style="margin-top:10px;">拖拽图片到这里哟</p> <div> <input type="file" style="display:none;" name="fileDragselect" multiple> <div> <ul> </ul> </div> </div> </div> <!-- 点击按钮上传文件 --> <div> <div> <button type="button"> 本地上传文件</button> <input type="file" style="display:none;" name="fileselect" multiple> </div> <div> <div> <ul> </ul> </div> </div> </div> </div> </div> </header> <script type="text/javascript"> //点击本地上传文件 $('#btn').click(() => { $('#fileInput').click(); }) $('#fileInput').change((event) => { var files = event.target.files; appendFile(files, '.list-btn'); }) //拖拽上传文件 在页面进行预览 上传form用到ajax const dragbox = document.querySelector('.dragFile'); dragbox.addEventListener('dragover', function(e) { e.preventDefault(); // 必须阻止默认事件 }, false); dragbox.addEventListener('drop', function(e) { e.preventDefault(); // 阻止默认事件 var files = e.dataTransfer.files; //获取文件 appendFile(files, '.list-drag') // code }, false); function appendFile(files, listName) { for(file of files) { let url = window.URL.createObjectURL(file); let liStr = ` <li> <div> <img src="" alt="文件" /> </div> </li> `; $(listName).append(liStr); } } </script> </body></html>