天天看點

利用createobjectUrl圖檔預覽以及上傳

步驟1:建立一個表單
<form class="form-horizontal" id="uploadForm" enctype="multipart/form-data">
<div class="form-group">
    <label for="Email" class="col-sm-2 control-label">Email</label>
    <div class="col-sm-10">
        <input type="email" class="form-control" id="Email" name="Email">
    </div>
</div>
<div class="form-group">
<label for="pic" class="col-sm-2 control-label">file input</label>
<div class="col-sm-10">
 <input type="file" id="upload" class="btn" onchange="getFullPath(this)" name="file" multiple="multiple" />

 </div>
 </div>
 <div class="form-group">
 <label for="pic" class="col-sm-2 control-label invisible ">file input</label>
 <div class="col-sm-10" id="imgHolder">

 </div>

 </div>
<div class="form-group">
 <label for="job" class="col-sm-2 control-label  ">job</label>
 <div class="col-sm-10" id="job" >
    <input type="checkbox" value="1" name="job"/>總經理
    <input type="checkbox" value="2" name="job"/>銷售經理
    <input type="checkbox" value="3" name="job"/>項目經理
 </div>
</div>

<div class="form-group">
    <div class="col-sm-12">
        <input type="button" id="sub" class="btn btn-primary center-block" value="submit">
    </div>
</div>
</form>
           

注意:這裡是多檔案預覽和上傳,是以在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 <= ) {
        return false;
    }

    for(var i = ; 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="<div style='position:relative;float:left' onmouseover='showX(this)'  onmouseout=' hideX(this)'>";
            //這裡 ./static 的 . 表示根路徑 
            tdHtml+="<img src='./static/image/a7.png' alt='123456464774' style='z-index:100;position:absolute;top:5px;right:0px;display:none'  onclick=\"delPic(this,'"
                    +newFileList[i].name+"')\"/>";
            tdHtml += "<img class='spPic' src='" + url + "' width='100px' height='100px'>";
            tdHtml += "</div>";
            $("#imgHolder").append(tdHtml);
        }
    }


}
           

我想這裡的fileList變量有人可能會有疑問,為什麼要設定這個變量。主要是為了上傳圖檔用的。下面會仔細說明的

2.函數validateUp()代碼

這個函數主要用來驗證圖檔是否符合要求的

var defaults = {
    fileType : [ "jpg", "png", "bmp", "jpeg", "JPG", "PNG", "BMP", "JPEG" ], // 上傳檔案的類型
    fileSize :  *  * 
// 上傳檔案的大小 10M
};
           
function validateUp(files) {
    var names = [];
    for (var j = ; j < fileList.length; j++) {
        names.push(fileList[j].name);
    }

    var arrFiles = [];// 替換的檔案數組
    for (var i = , file; file = files[i]; i++) {
        // 擷取檔案上傳的字尾名
        var newStr = file.name.split("").reverse().join("");
        if (newStr.split(".")[] != null) {
            var type = newStr.split(".")[].split("").reverse().join("");
            if (jQuery.inArray(type, defaults.fileType) > -) {
                // 類型符合,可以上傳
                if (file.size >= defaults.fileSize) {
                    parent.layer.msg(file.size);
                    parent.layer.msg('您這個"' + file.name + '"檔案大小過大');
                } else {
                    // 在這裡需要判斷目前所有檔案中
                    if ($.inArray(file.name, names) == -) {
                        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=,file;file=fileList[i];i++){
                    if (file.name == name) {
                        fileList.splice(i, );
                        //删除下标為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")[]);
    for (var i = ; 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>-1</value>
        </property>
        <property name="defaultEncoding">
            <value>UTF-8</value>
        </property>
</bean>

<!--在maven的pom.xml裡粘貼這個就行了-->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.2</version>
</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())!=-){
                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 多圖預覽