JS 中使用 FormData 上传文件 图片的方法 JQ 的 input file change 事件只触发一次
上传文件设置 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 class="postfile" type="file" multiple="multiple">');
}else{
$.alert({
title: '提示!',
content: "图片宽高不符合590*824!",
confirm: function(){
}
});
$('#imgUrl').replaceWith('<input class="postfile" 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 class="container">
<input type="file" name="file" value="上传" />
<div class="imgs">
<img src="" />
</div>
<div class="imgs">
<img src="" />
</div>
<div class="imgs">
<img src="" />
</div>
<div class="imgs">
<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 class="page-header">
<!-- 头部显示 -->
<div class="container upload ">
<div class="up-header center-block">
<h2>文件上传——两种形式</h2>
<div class="input-group" style="width:600px; display:flex;">
<input type="text" class="form-control" placeholder="在此处粘贴图片网址">
<button type="button" class="btn btn-primary">上传图片</button>
</div>
</div>
<div class="row">
<!-- 拖拽图片到这来 -->
<div class="col-md-5 col-md-offset-1 up-content dragFile">
<p style="margin-top:10px;">拖拽图片到这里哟</p>
<div class="up-area">
<input type="file" style="display:none;" name="fileDragselect" multiple>
<div class="row">
<ul class="list-group clearfix list-drag">
</ul>
</div>
</div>
</div>
<!-- 点击按钮上传文件 -->
<div class="col-md-5 up-content btnFile">
<div class="btn">
<button type="button" class="btn btn-success"> 本地上传文件</button>
<input type="file" style="display:none;" name="fileselect" multiple>
</div>
<div class="up-area">
<div class="row">
<ul class="list-group clearfix list-btn">
</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 class="list-group-item">
<div>
<img src="" alt="文件" />
</div>
</li>
`;
$(listName).append(liStr);
}
}
</script>
</body>
</html>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

你可能也喜欢
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论