闵超的主页

图片上传功能

2015-08-10
闵超

图片上传功能

最近在项目开发过程中出现了一个问题,一个表单中途改了需求,要求能进行上传附件(格式是PDF或者图片)

前台代码如下,

<form id="supplierForm" action="">
	<div class="row form-div">
		<p class="col-lg-12 col-md-12 col-sm-12 col-xs-12 form-title">附件信息</p>
		<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 form-group">
		<label for="business-licence">公司简介(营业执照/税务登记证/资质文件等)<span class="require">*</span></label>
		<div class="upload" id="upload1">
			<input class="file-input" type="file" id="business" onchange="handleBusiness()" > 
			<input	id="businesslicence" type="text"  value="" class="form-control" readonly="readonly">
			<a id="businessBtn" href="javascript:void(0);"
				class="btn btn-info" onclick="uploadBusiness()">上传</a>
		</div>
	</div>						
</form>

<!-- 图片的表单   -->
<form id="uploadForm" method="post" enctype="multipart/form-data"
	target="hiddenIframe" style="display: none; width: 0px; height: 0px;">
	<span id="fileContent"></span>
	<input type="submit" onclick="uploadFormSubmit()">
</form>

js代码

var businessFile = $("#business");
var businesslicence = $("#businesslicence");
function handleBusiness() {
	var of = $("#business");
	//修改属性
	of.attr("id", "uploadFile");
	of.attr("name", "uploadFile");
	$("#fileContent").empty();//清空表单
	$("#fileContent").append(of);//选中元素之后放入表单
	//将文件移动至上传表单
	var file = $("#uploadFile").val();
	function uploadFormSubmit(){
			var options = {
					type : 'POST',
					url : "${base}/uploaderSupplier.jspx",
					complete : function(data) {
						$("#businessPath").val(data.responseJSON.fileName);
						of.attr("id", "business");
						$("#upload1").append(of);
						layer.msg("简介文件上传成功!");
					}
				}
				$("#uploadForm").ajaxSubmit(options);
		}
		if(document.getElementById("uploadFile").files){
			var fileData = document.getElementById("uploadFile").files[0];
		}
		
		var ext = file.substring(file.lastIndexOf('.'), file.length).toUpperCase();
		if (ext == '.PNG' || ext == '.JPG' || ext == '.JPEG' || ext == '.GIF' || ext == '.PDF') {
			if (fileData.size <= 4 * 1024 * 1024) {
				businesslicence.val(businessFile.val());
				uploadFormSubmit();
			} else {
				layer.msg("文件最大不能超过4M!");
				$("#businesslicence").val("");
				of.attr("id", "business");
				$("#upload1").append(of);
			}
		} else {
			layer.msg("只能上传图片和PDF文件");
			$("#businesslicence").val("");
			of.attr("id", "business");
			
			$("#upload1").append(of);
			return;
		}
	};
	// 	点击上传按钮触发文件选择框
	function uploadBusiness() {
		businessFile.click();
	};

java后台代码:

/**
 * <p>功能简述:图片上传接口</p>
 * <p>细节描述:返回图片的保存路径,图片名前拼接日期</p>
 * @param request
 * @param response
 * @param model [参数说明]
 * @author minchao
 * @since [2017年6月30日]
 */
@RequestMapping(value = "/uploaderSupplier.jspx", method = RequestMethod.POST)
public void uploaderSupplier(HttpServletRequest request, HttpServletResponse response,ModelMap model) {

    response.setCharacterEncoding("UTF-8");  
    response.setHeader("Cache-Control", "no-cache");  
    response.setDateHeader("Expires", 0);    
    String fileName = "";
    String filePath = ""; 
    // 转型为MultipartHttpRequest:   
    MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;   
    // 获得文件:  
    MultipartFile filedata = multipartRequest.getFile("uploadFile");   
    System.out.print(filedata);
    if (filedata != null && !filedata.isEmpty()) {   
       // 获取图片的文件名  
       fileName = filedata.getOriginalFilename();  
       // 将图片上传到服务器  
       filePath=saveFile(request, fileName, filedata);    
       // System.out.println("上传文件 "+filePath+"成功");  
    }  
    System.out.println(request);
    JSONObject json = new JSONObject();
    json.put("success", true);
    json.put("status", 1);
    json.put("fileName", filePath);
    ResponseUtils.renderJson(response, json.toString());
}

/**
 * <p>功能简述:保存文件方法</p>
 * <p>细节描述</p>
 * @param request
 * @param newFileName
 * @param filedata
 * @return [参数说明]
 * @author minchao
 * @since [2017年6月30日]
 */
@Autowired
private KdSupplierMng kdSupplierMng;
public String saveFile(HttpServletRequest request, String newFileName,  
        MultipartFile filedata) {  
    String path = request.getSession().getServletContext().getRealPath("/r/cms/www/supAttachment/");
    String saveFilePath = path; 
    
    Date d = new Date(); 
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
    String dateNowStr = sdf.format(d); 
    String ext =  newFileName.substring(newFileName.lastIndexOf("."));
    newFileName = dateNowStr + ext;
    //System.out.println("文件名:" + newFileName); 
    // 构建文件目录  
    File tempFile = new File(saveFilePath);  
    if (!tempFile.exists()) {  
        tempFile.mkdirs();  
    }  
    // 保存文件到服务器  
    FileOutputStream fos;  
    try {  
        fos = new FileOutputStream(saveFilePath + "\\" + newFileName);  
        fos.write(filedata.getBytes());  
        fos.close();  
    }catch (Exception e) {  
        e.printStackTrace();  
    }  
    return "/r/cms/www/supAttachment/"+newFileName;  
} 

接口返回的存放图片的名称。

实现图片上传的方法是,新写一个表单,专门用来上传图片。由上传按钮来触发文件框的弹出选择文件窗口,接着,再由文件框的onchange()方法触发新表单的ajax上传文件功能。

注意,如果直接粘贴复制代码的话,需要导入jquery.form.js和layer.js文件。

当然,事情并不会就这样结束。

ie9 有两个坑:

第一个坑: getElementById(“uploadFile”).files[0]会报错,因为ie9是无法读取浏览器之外的本地文件的。

解决方法是:在var fileData = document.getElementById(“uploadFile”).files[0];//获取文件和var ext = file.substring(file.lastIndexOf(‘.’), file.length).toUpperCase();//判断尾缀z之间加一段判断代码

if(document.getElementById("uploadFile").files){
	var fileData = document.getElementById("uploadFile").files[0];
}else{
	 var fileEle = document.getElementById("uploadFile");
	 var fileData = null;
	 /*
    低版本IE由于JS安全问题,不允许JS访问本地文件,所以无法获取files, 对于低版本的IE可以使用ActiveXObject获取文件对象, 但是默认情况下
    ActiveXObject为不可用的, 所以要想使用此对象要先启用设置, 即:  Tools(工具) / Internet options(选项) / Security(安全) / Custom level(自定义级别)
    找到"Initialize and script ActiveX controls not marked as safe for scripting"设置为"Enable(not secure)"即可.
    初始化和脚本化ActiveX控件,标记为脚本安全
    */
var fso = new ActiveXObject("Scripting.FileSystemObject");

/*
    1. 获取文件路径
        出于安全性的考虑,低版本IE上传文件时屏蔽了真实的本地文件路径,
        以C:\fakepath\**取而代之, 所以默认情况下通过fileEle.value 不能获取到
        文件的真实路径.
        如果想获取真实路径, 有两种方式:
            1. 通过设置IE的安全设置, 即:
                Tools(工具) / Internet options(选项) / Security(安全) / Custom level(自定义级别)
                找到"Include local directory path when uploading files to a server"
                设置为的"Enable"
            2. 使用JS获取, 即:
                fileEle.select().blur();
                var filePath = document.selection.createRange().text;
*/
fileEle.select();
fileEle.blur();
var filePath = $("#uploadFile").val();
    /*
        FileExists:  判断 文件是否存在
        GetFile: 获取文件对象
    */
    if(fso.FileExists(filePath)){
    	fileData = fso.GetFile(filePath);
    }
    
}
console.log(fileData);

其中还要用户配合打开ie浏览器的安全限制

第二个坑:由于IE9的安全限制,会导致按钮触发文件选择框的时候会报错。JAVASCRIPT5的错误。

ie10以下有这个问题,为了安全性能考虑,只允许点击file文本的时候才可以上传,因此,需要设置一个透明的 < input type=”file”>浮动到自定义按钮上,设置透明度为0,即可解决此问题

这个的解决办法是将input文件框透明置顶,当点击空白处时自动触发文件选择。但这与需求相违背了。JIRA上测试始终给我报了个错,说是用户常用习惯不符,触发文件选择框都是由点击上传按钮开始触发。因此,就只能放大招将IE9屏蔽了。

综上所述。

后期如果我找到了好的上传插件,并且兼容IE9的。会后续补充在博客里。 如果您有好的上传插件或者更好的解决办法。希望您能在评论里留言告知,方便我学习。


Content

如果喜欢,打个赏,加个好友吧

扫描二维码打赏

扫描二维码打赏