前端圖片上傳的方式


html

type="file"指定input為文件選擇框,accept="image/*"表示文件框可以選擇圖片,multiple表示可以選擇多個文件。

<input id="upload" type="file" accept="image/*,audio/*,video/*" multiple onfocus="this.blur()"/>

capture拍照

capture='camera'表示圖片只能從相機實時抓取,禁止從相冊中選擇,需要注意的是capture和multiple同時使用時multiple會失效。

onfocus防止鍵盤彈出

onfocus="this.blur()"表示強制失去焦點,為了防止在某些手機瀏覽器上點擊時會彈出鍵盤選擇。

change事件

var upload = document.getElementById('upload');
upload.addEventListener('change', function() {
  var file = upload.files[0];  //獲取file文件
  console.info(file);
  console.info(file.size);
}, false);

file對象

File對象為獲取的文件對象,雖然有 getAsBinary()、getAsDataURL()和getAsText三個函數,但這個都是非標准函數,不能使用,需要使用FileReader讀取文件。

FileReader

1) readAsArrayBuffer():在返回的result屬性中將包含一個ArrayBuffer對象【緩沖數組,是一種用於呈現通用、固定長度的二進制數據的類型】以表示所讀取文件的內容。

2) readAsBinaryString():result屬性中將包含所讀取文件的原始二進制數據。

3) readAsDataURL():result屬性中將包含一個data: URL格式的字符串以表示所讀取文件的內容,即Base64。

4) readAsText():result屬性中將包含一個字符串以表示所讀取的文件內容。

圖片轉base64

var reader = new FileReader();
reader.readAsDataURL(file);   //文件讀取為base64
reader.onload = function(e) {
    //e代表事件,可以通過e.target獲取FileReader對象然后在獲取readAsDataURL讀取的base64字符
    console.log(e.target.result);  ////this代表FileReader,可以用this.result獲取讀取結果
    //預覽圖片
    var img = new Image();
    img.src = this.result;
    $('#previewDIv').append(img);
};

URL對象

blob 其實是 h5 表征的 Blob 對象數據, 可以使用Blob對象隱藏真實的資源路徑,在一定程度上可以起到數據的加密性,更多的是為了干擾爬蟲。

日常使用的一些音頻,視頻,圖片,我們都可以使用其Blob二進制數據流來表征數據,而非使用uri,就像經常用到的image sr 的dataUrl。

var url = URL.createObjectURL(file);
var img = new Image();
img.src = url;
img.onload = function(e) {
  window.URL.revokeObjectURL(this.src); //銷毀
}
console.log(url);

預覽前端選擇的文件

var img = new Image();
img.width = 200;
img.height = 200;
img.onload = function(){
	window.URL.revokeObjectURL(img.src);  //釋放通過URL.createObjectURL()創建的URL對象
}
img.src = window.URL.createObjectURL(file);   //用file對象創建blob協議的URL,用new Blob([file])
$('#preview').append(img);

Blob對象

Blob(binary large object)對象代表了一段二進制數據,就是一個包含只讀原始數據的類文件對象。

File接口基於Blob,繼承了Blob的功能,並且擴展支持了用戶計算機上的本地文件。

Blob構造函數生成文件

var blob = new Blob(["pwstrick"]);    //數組中添加DOMString對象
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);  //創建URL對象
a.download = "test.txt";   //HTML5新屬性,下載url的資源而不是導航,可以設置下載文件名
a.textContent = "下載";    //a標簽的文字
document.getElementsByTagName('body')[0].appendChild(a);

Blob構造函數生成圖片

var blob = new Blob([file]);    //數組中添加表單中獲取的file文件
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);  //創建URL對象
a.download = "test.jpg";   //HTML5新屬性,下載url的資源而不是導航,可以設置下載文件名
a.textContent = "下載";    //a標簽的文字
document.getElementsByTagName('body')[0].appendChild(a);

切割blob

//返回文件某一段的blob
function segment(file, start, end) {
    var reader = new FileReader();
    reader.onload = function(evt) {
        console.log(['Read bytes: ', start, ' - ', end].join(''));
        //console.info(this.result);  //文件的某一部分
    };
    var blob = file.slice(start, end);  //返回一個新的Blob對象,它包含有源Blob對象中指定范圍內的數據
    return reader.readAsBinaryString(blob);   //FileReader讀取blob對象
}

//切割某個文件
var start = 0;  //讀取起始位置
var chunk = 1024 * 1000; //10KB
var end = start + chunk;
var size = file.size;  //最大位置
while (start < size) {
    var b = segment(file, start, end);
    
    start = end;
    end = start + chunk;
    if (end > size) {
        end = size;
    }
}

FormData

用FormData對象,可以使用鍵值對來模擬一個完整的表單,然后使用XMLHttpRequest發送這個"表單"。

使用FormData的最大優點是可以異步上傳一個二進制文件。

var formData = new FormData();
formData.append("name", "value"); //普通鍵值對
formData.append("blob", blob); //傳遞一個blob對象,這里要用定制接口,不然后台保存的就是一個名為blob的文件
formData.append("file", file); //傳遞一個file對象

var oReq = new XMLHttpRequest();
oReq.open("POST", "./uploadController/upload");
oReq.onloadend = function () {  //請求結束時調用(包括成功:onload、失敗:onabort、onerror)
    console.info(oReq.responseText);  //打印請求返回結果
    var jsondata = JSON.parse(oReq.responseText);  //轉換為json對象
}
oReq.send(formData);  //發送表單

移動端圖片上傳

前端

html

<%--上傳文件后返回的圖片路徑--%>
<input hidden id="imgs" name="imgpath" value="${w.imgpath}">
<%--file輸入框,為了美化這里隱藏file輸入框,用a標簽觸發file點擊事件--%>
<input hidden type="file" id="sceneImg" multiple capture='camera' accept='image/*'>  
<%--拍照后預覽圖片--%>
<div id="preview" style="display:inline-block">
    <%--顯示時加載圖片--%>
    <c:forTokens items="${w.imgpath}" delims="," var="path">
        <img src="./${path}" style="width: 50px;height: 50px;margin-top:5px;">
    </c:forTokens>
</div>
<%--美化拍照按鈕,用一張帶鏈接的圖片去觸發file輸入框的click事件--%>
<a onclick='javascript:$("#sceneImg").click();'><img width="50px" height="50px" src="./asset/images/plus.jpg"></a>

js

$(function () {

    //拍照完畢時觸發input-file的change事件
    var sceneImg = document.getElementById("sceneImg");
    sceneImg.addEventListener("change",function () {
        var file = sceneImg.files[0];  //獲取到剛才拍照的圖片
        //預覽框中添加預覽圖片
        var img = new Image();
        /*img.width = 50;
        img.height = 50;*/
        img.style="width: 50px;height: 50px;margin-top:5px";
        img.onload = function(){
            window.URL.revokeObjectURL(img.src);   //釋放通過URL.createObjectURL()創建的URL對象
        }
        img.src = window.URL.createObjectURL(file);  //用blobURL的方式回顯
        $('#preview').append(img);
        $('#preview').append(" ");

        /*判斷圖片路徑是否超過指定長度*/
        if($('#imgs').val().length>450){
            layer.alert("圖片以達上線,禁止添加!!!",{title:'提示',offset: '150px',icon: 2});
            return false;
        }

        /*上傳照片*/
        var formData = new FormData();
        //添加字符串參數,這里是圖片即將上傳的文件夾
        formData.append("pathfolder",'img-'+'${handlercode}');
        //添加文件參數,這里也可以用blob
        formData.append('file', file);
        var oReq = new XMLHttpRequest();
        oReq.open("POST", "./uploadController/upload");
        oReq.onloadend = function () {  //請求結束時調用(包括成功:onload、失敗:onabort、onerror)
            var jsondata = JSON.parse(oReq.responseText);  //解析后端返回的json
            var imgPath = jsondata.path;
            var oldimgs = $('#imgs').val();
            /*成功后把圖片路徑加到input框中*/
            if(oldimgs.length>0){
                $('#imgs').val(oldimgs+","+imgPath);
            }else {
                $('#imgs').val(imgPath);
            }
        }
        oReq.send(formData);  //提交表單
    });
});

后端

package com.gmtx.common.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

/**
 * UploadController
 * @author: 秋雨
 * 2021-02-01 16:32
 **/
@Controller
@RequestMapping(value = "/uploadController", method = { RequestMethod.GET,RequestMethod.POST })
public class UploadController {

    /**
     * 上傳文件
     * @param req
     * @param resp
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/upload", method = {RequestMethod.POST })
    public String Upload(HttpServletRequest req, HttpServletResponse resp)throws Exception{
        req.setCharacterEncoding("utf-8");
        List<MultipartFile> files = ((MultipartHttpServletRequest) req).getFiles("file");
        MultipartFile file = files.get(0);
        String pathfolder = req.getParameter("pathfolder");

        if (file.isEmpty()) {
            String json = "{\"success\":false,\"message\":\"file is empty!\"}";
            resp.getOutputStream().write(json.getBytes("utf-8"));
        } else {
            Date time =new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String dateNowStr = sdf.format(time);
            //得到上傳文件的保存目錄,將上傳的文件存放於WEB-INF目錄下,不允許外界直接訪問,保證上傳文件的安全
            String folderPath = File.separator+"upload"+File.separator+pathfolder+File.separator+dateNowStr;
            String savePath = req.getSession().getServletContext().getRealPath(folderPath);
            File fileFolder = new File(savePath);
            //判斷上傳文件的保存目錄是否存在
            if (!fileFolder.exists() && !fileFolder.isDirectory()) {
                //創建目錄
                fileFolder.mkdirs();
            }
            //文件保存目錄
            String filesavepath = savePath+File.separator+file.getOriginalFilename();

            //IO流寫入
            OutputStream outputStream=new FileOutputStream(filesavepath);
            InputStream inputStream = file.getInputStream();
            //FileUtil.copyStream(inputStream, outputStream);
            byte[] bytes = new byte[1024];
            int len = 0;
            while((len = inputStream.read(bytes))!=-1){    //讀取到文件末尾的話可以讀到-1
                outputStream.write(bytes,0,len);
            }
            //flush輸出流
            outputStream.flush();
            //關閉流文件
            inputStream.close();
            outputStream.close();

            //圖片存儲路徑(web用)
            String webPath = folderPath+File.separator+file.getOriginalFilename();
            //因為URLEncoder.encode會把空格改為+號,要手動把加號改為%20
            webPath = URLEncoder.encode(webPath,"utf-8").replace("+", "%20");
            String json = "{\"success\":true,\"message\":\"文件上傳成功!\",\"path\":\""+ webPath +"\"}";

            resp.resetBuffer();
            resp.setContentType("text/html;charset=UTF-8");
            resp.getOutputStream().write(json.getBytes("utf-8"));
            resp.getOutputStream().flush();
        }
        return null;
    }
}

參考

https://www.cnblogs.com/hehuiself/p/7099861.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM