在本文中脐供,我們將研究帶有 #upload
ID 的 form
元素。
JSON 文件
它包含一個(gè)字段 #file
卖陵,帶有一種 type
類型儡嘶。使用 file
類型的字段可以指定 accept
參數(shù),并使用逗號(hào)分隔的接受文件類型列表芜飘。出于我們的目的务豺,我們將把上傳限制為 .json
文件。
<form id="upload">
<label for="file">文件上傳</label>
<input type="file" id="file" accept=".json">
<button>上傳</button>
</form>
我將使用一個(gè)簡(jiǎn)單的 userInfo.json
文件進(jìn)行測(cè)試嗦明。
{
"name": "O.O",
"age": "18",
"hobby": ["Eat", "sleep", "programming"]
}
監(jiān)聽(tīng)上傳
首先笼沥,我們將使用一些 DOM 操作基礎(chǔ)知識(shí)來(lái)檢測(cè)用戶何時(shí)提交文件。
我們將使用 document.querySelector()
方法獲取#upload
和 #file
元素娶牌,并將它們分別保存到 form
和 file
變量中奔浅。
let form = document.querySelector('#upload')
let file = document.querySelector('#file')
然后,我們將使用 Element.addEventListener()
方法來(lái)監(jiān)聽(tīng) form
元素上的 submit
事件诗良。我們將使用 handleSubmit()
函數(shù)作為回調(diào)函數(shù)汹桦。
form.addEventListener('submit', handleSubmit)
在 handleSubmit()
函數(shù)內(nèi)部,我們要做的第一件事是 event.preventDefault()
阻止表單重新加載頁(yè)面鉴裹。
/**
* 處理提交事件
* @param {Event} event 事件對(duì)象
*/
function handleSubmit (event) {
// 阻止表單重新加載頁(yè)面
event.preventDefault()
}
接下來(lái)营勤,我們將檢查 file
字段是否有要使用該文件處理的實(shí)際文件 file.value
屬性,然后檢查其 length
屬性壹罚。
如果沒(méi)有文件葛作,我們將使用 return
操作符結(jié)束回調(diào)函數(shù)。
function handleSubmit (event) {
event.preventDefault()
// 如果沒(méi)有文件猖凛,什么都不要做
if (!file.value.length) return
}
現(xiàn)在赂蠢,我們已經(jīng)準(zhǔn)備好上傳文件了。
使用 JavaScript 上傳和處理 JSON 文件
FileReader API 是一組異步方法辨泳,允許您處理和讀取文件內(nèi)容虱岂。
我們要做的第一件事是使用 new FileReader()
構(gòu)造函數(shù)創(chuàng)建一個(gè)新的 FileReader 實(shí)例玖院,并將其分配給 reader
變量。
function handleSubmit (event) {
event.preventDefault()
if (!file.value.length) return;
// 創(chuàng)建新的 FileReader() 對(duì)象
let reader = new FileReader()
}
要真正讀取文件第岖,我們可以使用 FileReader.readAsText()
方法难菌。
我們?cè)?reader
上調(diào)用它,并將文件作為參數(shù)傳遞給 reader
蔑滓。我們可以使用文件字段上的 files
屬性訪問(wèn)該文件郊酒。這將返回一個(gè)數(shù)組,因?yàn)?[type="file"]
可以支持多個(gè)文件键袱。
我們將使用括號(hào)表示法獲取第一個(gè)(在本例中是唯一的)文件燎窘。
function handleSubmit (event) {
event.preventDefault()
if (!file.value.length) return
let reader = new FileReader()
// 讀取文件
reader.readAsText(file.files[0])
}
這個(gè) API 是異步的,所以我們需要將 onload
事件處理程序附加到 reader
對(duì)象蹄咖。每當(dāng) reader
讀取文件時(shí)褐健,都會(huì)運(yùn)行該命令。
這需要在我們真正讀取文件之前聲明澜汤。
為了讓我們的代碼更有條理蚜迅,我們將使用一個(gè)命名函數(shù):logFile()
。我們不希望它立即運(yùn)行俊抵,所以在將其分配給事件時(shí)慢叨,我們不使用括號(hào)(()
)。
function handleSubmit (event) {
event.preventDefault()
if (!file.value.length) return
let reader = new FileReader()
// 將回調(diào)事件設(shè)置為在讀取文件時(shí)運(yùn)行
reader.onload = logFile
reader.readAsText(file.files[0])
}
logFile()
函數(shù)接收來(lái)自 FileReader 對(duì)象的隱式 event
參數(shù)务蝠,因此我們將其添加為參數(shù)拍谐。
event.target.result
屬性將是上傳的 JSON 文件的字符串化版本。我們可以將它傳遞給JSON.parse()
方法以從它獲取 JSON 對(duì)象馏段。
出于我們的目的轩拨,我們將記錄字符串和解析的 JSON。您可能希望在應(yīng)用程序中使用 JSON 文件的屬性院喜,將其保存到 localStorage
亡蓉,或者對(duì)其執(zhí)行其他操作。
function logFile (event) {
let str = event.target.result
let json = JSON.parse(str)
console.log('string', str)
console.log('json', json)
}
現(xiàn)在喷舀,每當(dāng)用戶提交 JSON 文件時(shí)砍濒,我們的代碼都會(huì)讀取它并將其記錄到控制臺(tái)。
圖像文件
更新我們的表單
對(duì)于本文硫麻,我們將更改 [type="file"]
輸入接受的文件類型爸邢。
我們想上傳圖像文件,所以我們將使用 image/*
作為 accept
的值拿愧。如果愿意杠河,您可以將特定的文件擴(kuò)展名指定為逗號(hào)分隔的列表,例如 .png, .jpg
。
<form id="upload">
<label for="file">文件上傳</label>
<input type="file" id="file" accept="image/*">
<button>上傳</button>
</form>
對(duì)于演示券敌,我還想在 UI 中顯示圖像唾戚,因此我將添加一個(gè) #app
元素,我們可以將圖像渲染到其中待诅。
<div id="app"></div>
使用 JavaScript 上傳圖片
首先叹坦,我們要更新我們的 handleSubmit()
函數(shù)。
我們將不使用 FileReader.readAsText()
方法卑雁,而是使用 FileReader.readAsDataURL()
方法募书,再次傳入文件。這將把文件作為 base64 編碼的數(shù)據(jù) URL 進(jìn)行處理序厉。
function handleSubmit (event) {
event.preventDefault()
if (!file.value.length) return
let reader = new FileReader()
reader.onload = logFile
reader.readAsDataURL(file.files[0])
}
接下來(lái),我們將使用 document.querySelector()
方法獲取 #app
元素并將其保存到變量中毕箍。
let app = document.querySelector('#app')
在 logFile()
事件處理程序函數(shù)中弛房,event.target.result
是圖像文件的數(shù)據(jù) URL 字符串。您可以將其保存到 localStorage
而柑,將其發(fā)送到服務(wù)器等等文捶。
因?yàn)槲覀兿朐?UI 中顯示它,所以我們將使用 document.createElement()
方法來(lái)創(chuàng)建一個(gè) img
元素媒咳。然后粹排,我們將從方法返回 event.target.result
的 FileReader.readAsDataURL()
設(shè)置為 src
屬性。
最后涩澡,我們將使用 Node.append()
方法將其注入 DOM顽耳。
function logFile (event) {
let str = event.target.result
let img = document.createElement('img')
img.src = str
app.append(img)
console.log(str)
}