1、若要把很多图片上传到相册中,这时使用Base64就不大好了,因为其占用的字节数很多,不利于数据库的维护。但是可以用来做预览,然后把真实图片上传到本地或服务器中【可参考文章使用Base64和Canvas上传图片】。
2、使用FileReader和FormData:
HTML:
<input style="opacity:0;width:1px" type="file" id="file_input" accept="image/*" multiple>选择图片</input>
JS【预览图片】:
var uploadFile_add = {
uploadFileArray:[]
};
// 点击添加图片
window.onload = function(){
var result,input = document.getElementById("file_input");
if(typeof FileReader==='undefined'){
result.innerHTML = "抱歉,你的浏览器不支持 FileReader";
input.setAttribute('disabled','disabled');
}else{
input.addEventListener('change',readFile,false);
}
function readFile(){
var iLen = this.files.length;
if(iLen > imageFileCount)
return alert("选择图片不能超过"+imageFileCount+"张");
for(var i=0;i<iLen;i++){
if (!input['value'].match(/.jpg|.gif|.png|.bmp/i)){ //判断上传文件格式
return alert("上传的图片格式不正确,请重新选择");
}
if(this.files[i].size > 1024 * 1024 * 2){
return alert("单张图片大小不超过2M");
}
uploadFile_add.uploadFileArray.push(this.files[i]); // 【存放选中的文件】
var reader = new FileReader();
var fileName = this.files[i].name; // 获取文件名
var fileType = this.files[i].type; // 文件后缀
reader.readAsDataURL(this.files[i]); // 转成base64,此方法执行完后,base64数据储存在reader.result里
reader.onload = function(e){
var aHtml = "<li class='mui-table-view-cell mui-media mui-col-xs-4'><a href='#'>";
aHtml += '<img class="mui-media-object" style="max-width:100%" src="'+e.target.result+'"/></a></li>';
$("#addPhoto").append(aHtml);
}
}
}
}
JS【使用FormData的append上传多张图片】:
var formData = new FormData();
$.each(uploadFile_add.uploadFileArray,function(k,v){
formData.append("fileList",v);
});
3、通过Ajax上传【其它参数可以放在URL上面】:
$.ajax({
url:"${base}/classedit/albums/toUploadOperation?zoneId=${zoneId}&albumsId=${albumsId}",
type:"post",
data: formData,
contentType:false,
processData:false,
success:function(result){
if(result.status=="200"){
alert(result.msg);
window.location.href='toClassAlbum';
}else if(result.status=="400"){
alert(result.msg);
window.location.reload();
}
}
});
① contentType设为false:jQuery不设置content-type请求头【定义网络文件的类型和网页的编码,决定文件接收方将以什么形式、什么编码读取这个文件】。
② processData设为false:jQuery不处理需要发送的数据【默认为true,发送的数据将被转换为对象以配合默认内容类型"application/x-www-form-urlencoded"。若要发送DOM树信息或者其它不希望转换的信息,需设置为false】。
4、Controller层:
@RequestMapping(value="toUploadOperation")
@ResponseBody
public Map<String,Object> uploadOperation(
HttpServletRequest request,HttpServletResponse response) throws Exception{
Map<String,Object> map = Maps.newHashMap();
String userId = (String)request.getSession().getAttribute("userId");
CommonsMultipartResolver csr = new CommonsMultipartResolver(request.getSession().getServletContext());
if(!csr.isMultipart(request)){
map.put("status", "400");
map.put("msg", "上传过程中出现错误,请联系管理员!");
return map;
}
MultipartHttpServletRequest mhsr = (MultipartHttpServletRequest)request;
Iterator<String> fileNames = mhsr.getFileNames();
while(fileNames.hasNext()){
List<MultipartFile> files = mhsr.getFiles(fileNames.next());
//图片地址为: 项目名称 /classId or personId/相册名称/年/月/日/图片名称
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String realOfImagePath = AlbumCommonConstants.IMG_UPLOAD_PATH + "/" + zoneId + "/" + albumsId + "/" + sdf.format(new Date());
String fileOrgName = "",fileRealName = "",fileSuffixName = "";
for (MultipartFile file : files) {
String photoId = UuidUtil.getUuid();
fileOrgName = file.getOriginalFilename();
fileRealName = fileOrgName.substring(0,fileOrgName.lastIndexOf("."));
fileSuffixName = fileOrgName.substring(fileOrgName.lastIndexOf(".")+1,fileOrgName.length());
File targetFile = new File(realOfImagePath, photoId + "." + fileSuffixName);
if(!targetFile.exists())
targetFile.mkdirs();
file.transferTo(targetFile); // 小文件直接拷贝
5、通过XMLHttpRequest上传【可以显示上传百分比】:
① XMLHttpRequest可以传送所有类型的数据,且在不同类型的浏览器上的实现是兼容的。
② XMLHttpRequest对象属性:
| readystatechange:状态改变的事件触发器【由服务器触发而不是用户】。
| readyState:对象状态【0未初始化、1读取中、2已读取、3交互中、4完成】。
| responseText:服务器进程返回数据的文本【一般是Json字符串】。
| responseXML:服务器进程返回兼容DOM的XML文档对象。
| status:服务器返回的状态码【200表示成功,404表示未找到等等】。
| statusText:服务器返回的状态文本信息。
var url = "${base}/classedit/albums/toUploadOperation?zoneId=${zoneId}&albumsId=${albumsId}";
var xhr = new XMLHttpRequest();
// 请求类型【true为异步处理请求,false为同步处理请求】
xhr.open("post", url, true);
// 上传进度
xhr.upload.addEventListener("progress", function(result) {
if (result.lengthComputable) {
var percent = (result.loaded / result.total * 100).toFixed(2);
}
}, false);
// 事件监听
xhr.addEventListener("readystatechange", function() {
var result = xhr;
if (result.status!=200) {
console.log('上传失败', result.status, result.statusText, result.response);
alert(JSON.parse(result.responseText).msg);
window.location.reload();
}else if(result.readyState==4) {
console.log('上传成功', result);
alert(JSON.parse(result.responseText).msg);
window.location.href='toClassAlbum';
}
});
// 开始上传
xhr.send(formData);
6、Controller层加上 @RequestParam(value = "fileList") MultipartFile[] fileList参数。
@RequestMapping(value="toUploadOperation")
@ResponseBody
public Map<String,Object> uploadOperation(
@RequestParam(value="zoneId") String zoneId,@RequestParam(value="albumsId") String albumsId,
@RequestParam(value = "fileList") MultipartFile[] fileList,
HttpServletRequest request,HttpServletResponse response) throws Exception{
Map<String,Object> map = Maps.newHashMap();
String userId = (String)request.getSession().getAttribute("userId");
String accountName = zoneDataService.getZoneDataByOwnerId(userId).getOwnerName();
String content = gzoneAlbumsService.selectGzoneAlbumsByAlbumId(albumsId).getAlbumsName();
//图片地址为: 项目名称 /classId or personId/相册名称/年/月/日/图片名称
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String realOfImagePath = AlbumCommonConstants.IMG_UPLOAD_PATH + "/" + zoneId + "/" + albumsId + "/" + sdf.format(new Date());
String fileOrgName = "",fileRealName = "",fileSuffixName = "";
for(int i=0;i<fileList.length;i++){
MultipartFile file = fileList[i];
String photoId = UuidUtil.getUuid();
fileOrgName = file.getOriginalFilename();
fileRealName = fileOrgName.substring(0,fileOrgName.lastIndexOf("."));
fileSuffixName = fileOrgName.substring(fileOrgName.lastIndexOf(".")+1,fileOrgName.length());
File targetFile = new File(realOfImagePath, photoId + "." + fileSuffixName);
if(!targetFile.exists())
targetFile.mkdirs();
file.transferTo(targetFile); // 小文件直接拷贝
----- END -----