2020-04-01

我們都知道站削,html5中有個(gè)input type=file元素坊萝。用該元素可以實(shí)現(xiàn)頁面上傳文件的功能

但一般的做法只是簡單的在表單中操作,我來研究一下深層?xùn)|西

想要了解它许起,就要知道它的內(nèi)置對象十偶,files

頁面上寫一個(gè)input,然后選倆個(gè)圖片园细,打印這個(gè)input對象

("input[name='file1']").change( function(e){ console.log(("input[name='file1']"))
})
發(fā)現(xiàn)有下列值惦积,在0中,有一個(gè)files對象

我們發(fā)現(xiàn)input選擇的文件被記錄到了這個(gè)對象中猛频,這個(gè)是fileList對象狮崩,是一個(gè)只讀對象,不能修改

因?yàn)樗荒苄薷穆寡埃院茈y實(shí)現(xiàn)對已選中多個(gè)文件的刪除某個(gè)文件等操作

里面記錄了文件的name睦柴,size,type烈和,和修改時(shí)間等爱只,可知這個(gè)對象只存放了一些文件的信息,相當(dāng)于是本地文件的索引招刹,并不是把文件放到input中了恬试,上傳文件時(shí)它會再去找到實(shí)際的本地文件

fileList數(shù)組包含多個(gè)File對象,F(xiàn)ile對象是繼承與Blob對象的疯暑,關(guān)于file训柴,url,blob,dataUrl可以詳細(xì)查查

一般url可以是本地地址妇拯,http地址等

blob對象一般的形式是:blob:http://192.168.100.151:8080/1148dcd6-952e-4478-823d-21b37e537c2f幻馁,屬于瀏覽器對象

dataUrl 一直格式是:以data:image/jpeg;base64,這種類似形式打頭的一串很長的字符串洗鸵。

這三種形式在img標(biāo)簽中src屬性都可以調(diào)用。

File對象有name仗嗦,size,lastModified屬性

File對象的創(chuàng)建:

var file1=new File([blob], "aa.png",{type:"image/jpg"}); //第一個(gè)參數(shù)是Blob對象或者dataUrl膘滨,第二個(gè)參數(shù)是文件名,三個(gè)參數(shù)可選稀拐,規(guī)定文件類型

注意:第一個(gè)參數(shù)必須是對象火邓,不能是轉(zhuǎn)換成的字符串,比如uniapp或者微信小程序的chooseImage方法返回的blob的url德撬,他是一個(gè)字符串铲咨,這樣生成的File對象只是將url字符串變成文件了,不是文件本身r押椤O死铡!

想把blob字符串變成Blob對象隆檀,可以用es6的:const blob = await fetch(image.path).then(r => r.blob())

或者用傳統(tǒng)的XHR或者ajax也行摇天,就是把blob對象根據(jù)url給獲取出來就行。

利用這個(gè)files對象恐仑,我們可以實(shí)現(xiàn)很多功能闸翅,例如:

一.選擇圖片未經(jīng)后端顯示預(yù)覽圖片

方法1:利用window的url工具將文件生成url,再將url賦值給img的src屬性菊霜,顯示出選中圖像

順便提一下坚冀,input中控制選中類型加一個(gè)accept屬性就行了,只會顯示設(shè)定的文件類型

<input id="file1" type="file" name="file1" multiple="multiple" accept=".doc鉴逞,.jpg">
('.fbpj-camera').change(function(event) { //('.dianpuzhuangxiu .addmokuai .block .shuoming1 .pic .pic1').children().remove();
// 根據(jù)這個(gè) <input> 獲取文件的 HTML5 js 對象
var files = event.target.files, file;
if (files && files.length > 0) {
// 獲取目前上傳的文件
file = files[0];
// 來在控制臺看看到底這個(gè)對象是什么
console.log(file);
// 那么我們可以做一下諸如文件大小校驗(yàn)的動作
if(file.size > 1024 * 1024 * 2) {
alert('圖片大小不能超過 2MB!');
return false;
}
// !!!!!!
// 下面是關(guān)鍵的關(guān)鍵记某,通過這個(gè) file 對象生成一個(gè)可用的圖像 URL
// 獲取 window 的 URL 工具
var URL = window.URL || window.webkitURL;
// 通過 file 生成目標(biāo) url
var imgURL = URL.createObjectURL(file);
// 用這個(gè) URL 產(chǎn)生一個(gè) <img> 將其顯示出來
$('.fbpj .container').prev().find("img").attr('src', imgURL);
// 使用下面這句可以在內(nèi)存中釋放對此 url 的伺服,跑了之后那個(gè) URL 就無效了
//URL.revokeObjectURL(imgURL);
}
});
方法二:利用html5的FileReader()讀取文件

*前提是瀏覽器支持的話

if(window.FileReader) {
var fr = new FileReader();
// add your code here
}
else {
alert("Not supported by your browser!");
}
<script type="text/javascript">
function showPreview(source) {
var file = source.files[0];
if(window.FileReader) {
var fr = new FileReader();
fr.onloadend = function(e) {
document.getElementById("portrait").src = e.target.result;
};
fr.readAsDataURL(file); //也是利用將圖片作為url讀出
}
}
</script>

<input type="file" name="file" οnchange="showPreview(this)" />
<img id="portrait" src="" width="70" height="75">
FileReader還有一些其他用法

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="oscar999">
<title></title>
<script>
function handleFiles(files)
{
if(files.length)
{
var file = files[0];
var reader = new FileReader();
reader.onload = function()
{
document.getElementById("filecontent").innerHTML = this.result;
};
reader.readAsText(file); //作為字符串讀出
//reader.readAsText(file,'gb2312'); //默認(rèn)是用utf-8格式輸出的构捡,想指定輸出格式就再添加一個(gè)參數(shù)液南,像txt的ANSI格式只能用國標(biāo)才能顯示出來
}
}
</script>

</head>
<body>

<input type="file" id="file" οnchange="handleFiles(this.files)"/>
<div id="filecontent"></div>
</body>
</html>
readAsText一般只能讀取txt,html等等文件,局限性較大勾徽,比如想要前端讀excel文件滑凉,由于解決文件編碼問題較為復(fù)雜,需要用到j(luò)s-xlsx插件喘帚,具體可百度方法畅姊。

常用API:

FileReader.readAsDataURL(File) //轉(zhuǎn)換成base64格式

FileReader.readAsText() //轉(zhuǎn)換成字符串格式

FileReader.readAsArrayBuffer(File) //轉(zhuǎn)換成ArrayBuffer格式

FileReader.readAsBinaryString(File) //轉(zhuǎn)換成原始二進(jìn)制格式(貌似已被廢除)

FileReader.onload = function (e) { console.log(e.target.result) } //在上述讀取事件完成時(shí)觸發(fā)

二.文件拖拽的方法保存文件

關(guān)于文件拖拽下面有注釋,我主要說一下怎么給用js給input賦值吹由,而不是手動去選文件

因?yàn)橥献У膮^(qū)域只是一個(gè)div若未,無法進(jìn)行上傳操作,所以需要加一個(gè)form和input倾鲫,讓拖拽進(jìn)去的文件進(jìn)入input中粗合。

取出files后萍嬉,用$("#file1")[0].files=files;將文件賦值給input,注意賦值的必須是fileList對象隙疚,不要試圖只放進(jìn)去一個(gè)文件壤追,fileList只讀。

然后用h5中的FormData將form轉(zhuǎn)化供屉,提交即可

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
.container{
width:300px;height: 300px;
border:2px dashed #ddd;
text-align: center;
padding:50px;
}
</style>
<title>
培訓(xùn)活動列表
</title>
</head>
<body>
<div class="container">
拖拽進(jìn)入
</div>
<form id="form1" method="post" enctype="multipart/form-data">
<input type="file" name="file1" id="file1" value="" />
</form>
<script type="text/javascript">
('.container').bind('dragenter dragover', ignoreDrag);(".container").on({drop:function(e){
var flag=true;
e.preventDefault();
//jquery的file要去e.originalEvent里面拿大诸,拖拽獲取files的方式與input的不同
var files = e.originalEvent.dataTransfer.files;
//var files = e.dataTransfer.files; 原生的話這樣就可以獲取
for(var i=0;i<files.length;i++){
myFileReader(files[i],function(result,file){
if(result){
//文件
console.log(file.name)

            }else{
                //文件夾
                console.log("不要上傳文件夾")
                flag=false;
            }
        });
    }
    if(flag){
        $("#file1")[0].files=files;   //關(guān)鍵:將取到的文件賦值給input,用于ajax提交文件9嶝浴!焙贷!
        var formData = new FormData($("#form1")[0]);     
        $.ajax({
            url : "/it/orderManage/saveActivity",
            type : 'POST',
            data : formData,
            // 告訴jQuery不要去處理發(fā)送的數(shù)據(jù)
            processData : false,
            // 告訴jQuery不要去設(shè)置Content-Type請求頭
            contentType : false,
            async : true,
            success : function(ret) {
                //alert("上傳成功")
                if(ret){
                    $("#trainInfoModal").modal("hide");
                    layer.alert("保存成功")
                    $('#orderTable').bootstrapTable("refresh");
                    $("#trainInfoModal input").val("");
                    $("#trainInfoModal textarea").val("");

                }
            }
        });
    }
    console.log(files);
}})

function ignoreDrag(e) {e.originalEvent.stopPropagation();
    e.originalEvent.preventDefault();
}

function myFileReader(file, callback){
    if(!window.FileReader){
        callback(true,file);
        return false;
    }
    var fr = new FileReader();
    fr.readAsDataURL(file);
    fr.οnlοad=function(e){
        callback(true,file);
    }
    fr.οnerrοr=function(e){  //不好判斷是否是文件夾撵割,通過上傳報(bào)錯(cuò)可以判斷是文件夾
        callback(false,file);
    }
    return true;
};

</script>
</body>
</html>
后臺獲取文件還是用MutipartFile[]接收

public String saveActivity(@RequestParam HashMap<String, String> param,
//@RequestParam(value = "banner") MultipartFile[] files,
@RequestParam(value = "file1") MultipartFile[] file1,
HttpServletRequest request,
String fileNames,
String TID, HttpServletRequest req) {

三.vue+axios 上傳文件
無論ajax還是axios,都不是直接用表單提交的辙芍,都是 要用 new FormData()轉(zhuǎn)化一下啡彬。

所以axios方法與ajax方法類似

<input type="file" class="inputBtn" @change="uploadMarketingForm">
uploadMarketingForm(e){
console.log(e)
var fileName=e.target.files[0].name; //文件名
var fileSize=e.target.files[0].size; //文件大小
var param = new FormData();
//添加表單參數(shù),如果后臺用文件數(shù)組接收
//param.append("file", e.target.files);
//如果后臺只接收單一文件
param.append("file", e.target.files[0]);
//設(shè)置表頭類型
const config = {
headers: { "Content-Type": "multipart/form-data" }
};
this.axios.post("/.../uploadTest", param, config).then(res => {
console.log(res);
});
},
在java spring mvc中還是這么接收

@ResponseBody
@RequestMapping(value = "uploadTest", produces = "text/plain;charset=UTF-8")
public String uploadTest(@RequestParam Map<String,String> param,@RequestParam(value = "file") MultipartFile[] file1,
HttpServletRequest request) throws IOException {
RetBase retBase = new RetBase();
//文件可以在參數(shù)中用MultipartFile[](多文件) 或者 MultipartFile (單一文件)接收
//也可以像這樣在request中接收
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
MultipartFile multifile = multipartRequest.getFile("file"); // 通過參數(shù)名獲取指定文件
String fileName = multifile.getOriginalFilename();
// 獲取文件后綴
String prefix=fileName.substring(fileName.lastIndexOf("."));
// 用uuid作為文件名故硅,防止生成的臨時(shí)文件重復(fù)
final File file = File.createTempFile(UUID.randomUUID().toString(), prefix);
// MultipartFile to File
return JSON.toJSONString(retBase, SerializerFeature.WriteMapNullValue);

————————————————
版權(quán)聲明:本文為CSDN博主「lianzhang861」的原創(chuàng)文章庶灿,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明吃衅。
原文鏈接:https://blog.csdn.net/lianzhang861/java/article/details/80283120

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末往踢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子徘层,更是在濱河造成了極大的恐慌峻呕,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趣效,死亡現(xiàn)場離奇詭異瘦癌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)跷敬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人碌补,你說我怎么就攤上這事捎稚。” “怎么了拥褂?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵抡驼,是天一觀的道長。 經(jīng)常有香客問我肿仑,道長致盟,這世上最難降的妖魔是什么碎税? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮馏锡,結(jié)果婚禮上雷蹂,老公的妹妹穿的比我還像新娘。我一直安慰自己杯道,他們只是感情好匪煌,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著党巾,像睡著了一般萎庭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上齿拂,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天驳规,我揣著相機(jī)與錄音,去河邊找鬼署海。 笑死吗购,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的砸狞。 我是一名探鬼主播捻勉,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼刀森!你這毒婦竟也來了踱启?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤研底,失蹤者是張志新(化名)和其女友劉穎禽捆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體飘哨,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胚想,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了芽隆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浊服。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖胚吁,靈堂內(nèi)的尸體忽然破棺而出牙躺,到底是詐尸還是另有隱情,我是刑警寧澤腕扶,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布孽拷,位于F島的核電站,受9級特大地震影響半抱,放射性物質(zhì)發(fā)生泄漏脓恕。R本人自食惡果不足惜膜宋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望炼幔。 院中可真熱鬧秋茫,春花似錦、人聲如沸乃秀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跺讯。三九已至枢贿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刀脏,已是汗流浹背局荚。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留火本,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓聪建,卻偏偏與公主長得像钙畔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子金麸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 零基礎(chǔ)入門 Android 零基礎(chǔ)與進(jìn)階知識學(xué)習(xí) Roadmap 概述 本文適用于: 零基礎(chǔ)擎析,想學(xué)...
    王巖_shang閱讀 346評論 0 1
  • 2.1、方法的重載:overload 概念:一個(gè)類中的挥下,一個(gè)功能方法的多種體現(xiàn)形式(有不同的方法體)揍魂。 舉例: ...
  • 一、 語法 .innerHTML =? :寫入到頁面棚瘟; document.getElementById(“...
    執(zhí)著_7fb1閱讀 98評論 0 0
  • 今天在shell腳本用到var截取文件名现斋,感覺挺實(shí)用的,所以抄了一下稍微比較全面的的筆記偎蘸,之后會繼續(xù)補(bǔ)充庄蹋,下面是工...
    爛筆頭2020閱讀 404評論 0 2
  • “ 作為一名土生土長的夏邑人,我對自己的家鄉(xiāng)和方言卻知之甚少迷雪。而‘言續(xù)’給我機(jī)會去深入了解它限书。它在地圖上或許只是一...
    北京的京閱讀 413評論 0 0