步骤1:创建一个表单
注意:这里是多文件预览和上传,所以在file元素后面要有multiple=”multiple”
步骤2:利用createObjectUrl预览以及ajax上传
1. 获取图片在div中预览显示
var fileList = [];
function getFullPath(obj){
var file=document.getElementById("upload");
var newFileList=file.files;// 获取的图片文件
newFileList = validateUp(newFileList);
if (newFileList.length <= 0) {
return false;
}
for(var i = 0; i < newFileList.length; i++){
//这里try catch 是为了防止苹果浏览器 5.17 因为苹果浏览器不支持createobjecturl
try{
var url=window.URL.createObjectURL(newFileList[i]);
}
catch(err){
}finally{
fileList.push(newFileList[i]);
var tdHtml="";
//这里 ./static 的 . 表示根路径
tdHtml+="
+newFileList[i].name+"')\"/>";
tdHtml += "";
tdHtml += "";
$("#imgHolder").append(tdHtml);
}
}
}
我想这里的fileList变量有人可能会有疑问,为什么要设置这个变量。主要是为了上传图片用的。下面会仔细说明的
2.函数validateUp()代码
这个函数主要用来验证图片是否符合要求的
var defaults = {
fileType : [ "jpg", "png", "bmp", "jpeg", "JPG", "PNG", "BMP", "JPEG" ], // 上传文件的类型
fileSize : 1024 * 1024 * 10
// 上传文件的大小 10M
};
function validateUp(files) {
var names = [];
for (var j = 0; j < fileList.length; j++) {
names.push(fileList[j].name);
}
var arrFiles = [];// 替换的文件数组
for (var i = 0, file; file = files[i]; i++) {
// 获取文件上传的后缀名
var newStr = file.name.split("").reverse().join("");
if (newStr.split(".")[0] != null) {
var type = newStr.split(".")[0].split("").reverse().join("");
if (jQuery.inArray(type, defaults.fileType) > -1) {
// 类型符合,可以上传
if (file.size >= defaults.fileSize) {
parent.layer.msg(file.size);
parent.layer.msg('您这个"' + file.name + '"文件大小过大');
} else {
// 在这里需要判断当前所有文件中
if ($.inArray(file.name, names) == -1) {
arrFiles.push(file);
} else {
parent.layer.msg('您这个"' + file.name + '"图片已经存在');
}
}
} else {
parent.layer.msg('您这个"' + file.name + '"上传类型不符合');
}
} else {
parent.layer.msg('您这个"' + file.name + '"没有类型, 无法识别');
}
}
return arrFiles;
}
说明:这里弹出框是利用layer插件。
3.删除预览图片功能
//鼠标移动到图片上时,右上角显示关闭按钮
function showX(o){
$(o).find('img:first').css('display','block');
}
//当鼠标移开,隐藏右上角关闭按钮
function hideX(o) {
$(o).find('img:first').css('display', 'none');
}
//删除图片
function delPic(o,name){
layui.use('layer', function(){
var layer = layui.layer;
layer.confirm('你确定要删除该图片吗?',{
btn:['确定','取消'],
shade:false
//不显示遮罩
},function(index){
for(var i=0,file;file=fileList[i];i++){
if (file.name == name) {
fileList.splice(i, 1);
//删除下标为i的图片
var parent=document.getElementById("imgHolder");
var div=parent.getElementsByTagName("div");
parent.removeChild(div[i]);
break;
}
}
layer.close(index);
})
});
}
这里的删除是移除div里的图片 不是真正的从file元素里删除。因为file元素是只读元素。
4.提交表单
这里我利用formData来获取表单的数据
//提交
$(function(){
$("#sub").click(function(){
//event.preventDefault();
formSubmit();
})
})
function formSubmit(){
//如果是多图片的话,这种形式formdata只能获取到最后一张图片。所以要用到下面的for循环。将其他图片放入到formdata中
//var data=new FormData($("#uploadForm")[0]);
//这个 length-1 是因为在上一句初始化formdata时,已经把最后一张图片放入formdata中了
//但是如果 之前选中了 图片 之后又删除了(这个删除是无法真正从input file里删除的,仍然会在上一句的初始化中获取到图片)
//所以 不建议这种写法
/*for (var i = 0; i < fileList.length-1; i++) {
if (fileList[i] != null) {
data.append("file", fileList[i]);
}
}*/
//先将input file清空
var file=document.getElementById("upload");
file.value="";
var data=new FormData($("#uploadForm")[0]);
for (var i = 0; i < fileList.length; i++) {
if (fileList[i] != null) {
// 这里的名字要和file元素的name值不同,如果相同的话,上传之后会多出来一个0kb的文件
data.append("files", fileList[i]);
}
}
//data.append("Email","345");
//var email=data.get("Email");
$.ajax({
type:"post",
url:'./emp2',
data : data,
processData : false,
contentType : false,
success : function(data) {
//alert("success");
location.reload();
},
error : function(e) {
alert(e.responseText);
}
})
}
看了我上面的注释可以知道 formdata只能获取一张图片(FormData中的属性值接受的是单个文件信息,不能是复合性的对象)。前面我们的变量fileList就是把所要要上传的图片获取到 然后赋值给formData. 最后利用ajax上传图片
注意: processData : false, contentType : false,这个很重要。一定要写上去。这两个是告诉jq 不要去处理发送的数据和不要去设置Content-Type请求头
具体细节参考这篇博客,说的比我仔细(这位博主应该是前端大牛):http://www.cnblogs.com/imwtr/p/5924042.html#3530655
步骤3:java后台接收
接收之前 要有相应的上传包。还要在配置里写上相关的bean。如下:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>-1value>
property>
<property name="defaultEncoding">
<value>UTF-8value>
property>
bean>
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.3.2version>
dependency>
后台接收代码
@ResponseBody
@RequestMapping(value="/emp2",method= RequestMethod.POST)
public Msg testFormAdd(HttpServletRequest req,
@RequestParam("files") MultipartFile[] file) throws IOException, ServletException{
String email= req.getParameter("Email");
String job=req.getParameter("job");
fileUpload(req,file);
System.out.println("ok"+email);
return Msg.success();
}
public void fileUpload(HttpServletRequest req, MultipartFile[] file) throws IOException {
for(MultipartFile item : file){
String fileName=item.getOriginalFilename();
//获取输出流
OutputStream os=new FileOutputStream("E:/"+new Date().getTime()+fileName);
//获取输入流
InputStream is=item.getInputStream();
int temp;
//一个一个字节的读取并写入
while((temp=is.read())!=-1){
os.write(temp);
}
os.flush();
os.close();
is.close();
}
}
注意:file元素的name是file,formdata里的fileList的key是files.所以接收的也是files.如果后台你写的是file,接收到的就是0kb的文件了。
后台文件接收方式有多种,我这里用的是流。具体的可以看一下这个博客:
http://www.cnblogs.com/fjsnail/p/3491033.html。
里面有接收方式的对比。
********************************************2018-04-22 更*********************************
FileReader对象的readAsDataURL方法 也可以实现预览; 可以将读取到的文件编码成Data URL。Data URL是一项特殊的技术,可以将资料(例如图片)内嵌在网页之中,不用放到外部文件。使用Data URL的好处是,您不需要额外再发出一个HTTP 请求到服务器端取得额外的资料;而缺点便是,网页的大小可能会变大。它适合应用在内嵌小图片,不建议将大图像文件编码成Data URL来使用。您的图像文件不能够超过浏览器限定的大小,否则无法读取图像文件。
readAsDataURL方法会使用base-64进行编码,编码的资料由data字串开始,后面跟随的是MIME type,然后再加上base64字串,逗号之后就是编码过的图像文件的内容。
题外话:
thunder://QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==
就是base64编码后的地址,所以以后看到这种:一堆连续字母,最后有1~2个”=”的代码就是base64。
base64:URL就是URL地址是base64编码的。
有时想要读取的文件太大,想要分段进行读取;或者只想要读取文件部分的内容,这时您可以将文件切割 利用webkitSlice 或mozSlice
具体 参考:http://blog.okbase.net/jquery2000/archive/1296.html
h5多图上传
angular4 多图预览