JavaScript如何在前端代碼中讀、寫本地文件
一,在前端代碼JavaScript中讀寫文件的限制與處理
在前端 JavaScript 中,瀏覽器環(huán)境沒(méi)有直接提供操作文件系統(tǒng)的能力。也就是說(shuō),你不能像在 Node.js 環(huán)境中那樣,使用 fs 模塊來(lái)刪除或創(chuàng)建文件。這是因?yàn)闉g覽器出于安全性的考慮,不允許網(wǎng)頁(yè)隨意訪問(wèn)用戶的文件系統(tǒng),以防止?jié)撛诘膼阂庑袨椤?/p>
然而,瀏覽器確實(shí)提供了一些有限的文件操作能力,主要是通過(guò)以下幾種方式:
1,文件上傳和下載
- 文件上傳: 可以通過(guò) <input type="file">
元素讓用戶選擇文件,然后通過(guò) JavaScript 讀取文件內(nèi)容。
- 文件下載: 可以通過(guò)創(chuàng)建 Blob 對(duì)象和使用 a
標(biāo)簽的 download
屬性來(lái)觸發(fā)文件下載。
2,F(xiàn)ile API
2,F(xiàn)ile System Access API
- File System Access API
是現(xiàn)代瀏覽器(主要是在 Chromium 內(nèi)核的瀏覽器)引入的一種新 API,它允許網(wǎng)頁(yè)直接與用戶的文件系統(tǒng)交互,創(chuàng)建、讀取、寫入和刪除文件。這是當(dāng)前瀏覽器提供的最接近文件系統(tǒng)操作的能力。
二,讀文件
(一)最簡(jiǎn)單方式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>讀文件</title> </head> <body> <input type="file" id="fileInput"> <button id="processButton">Process and Download</button> <script> document.getElementById('processButton').addEventListener('click', function () { const fileInput = document.getElementById('fileInput'); const file = fileInput.files[0]; if (file) { const reader = new FileReader(); reader.onload = function (e) { // 讀取文件內(nèi)容 let content = e.target.result; console.log(content); }; // 開始讀取文件 reader.readAsText(file); } else { alert('Please select a file first!'); } }); </script> </body> </html>
HTML 部分:
- - 我們創(chuàng)建了一個(gè)文件輸入框 (
<input type="file">
) 讓用戶選擇文件。
JavaScript 部分:
- - 我們創(chuàng)建了一個(gè) FileReader 對(duì)象來(lái)讀取選中的文件。
- - 使用
reader.onload
指定成功讀取文件時(shí)要做什么。 - - 使用
reader.readAsText(file)
開始以文本形式讀取文件。
(二)讀取大文件
在上面的代碼中,文件的讀取是通過(guò) FileReader 的 readAsText()
方法完成的。這個(gè)方法確實(shí)會(huì)一次性將整個(gè)文件內(nèi)容加載到內(nèi)存中。對(duì)于小型文件來(lái)說(shuō)這沒(méi)有問(wèn)題,但如果文件非常大,可能會(huì)導(dǎo)致內(nèi)存占用過(guò)高,影響性能,甚至導(dǎo)致頁(yè)面崩潰。
1,分片讀取
使用 FileReader 的 readAsArrayBuffer()
方法,然后使用 Blob 的 slice()
方法來(lái)分塊讀取文件。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>讀文件</title> </head> <body> <input type="file" id="fileInput"> <button id="processButton">Process</button> <script> document.getElementById('processButton').addEventListener('click', function () { const fileInput = document.getElementById('fileInput'); const file = fileInput.files[0]; if (file) { const CHUNK_SIZE = 1024 * 1024; // 1MB 分塊大小 let offset = 0; // 遞歸讀取文件的函數(shù) function readNextChunk() { // 檢查是否已經(jīng)讀取到文件末尾 if (offset >= file.size) { console.log("File processing complete."); return; } // 讀取當(dāng)前塊 const chunk = file.slice(offset, offset + CHUNK_SIZE); const reader = new FileReader(); reader.onload = function (e) { // 處理當(dāng)前塊的數(shù)據(jù) let content = e.target.result; console.log(`Processing chunk from ${offset} to ${offset + CHUNK_SIZE}`); console.log(content); // 此處可以進(jìn)行更復(fù)雜的處理 // 更新偏移量,并讀取下一塊 offset += CHUNK_SIZE; readNextChunk(); }; reader.onerror = function (e) { console.error("Error reading file chunk:", e); }; // 開始讀取當(dāng)前塊 reader.readAsText(chunk); } // 開始讀取第一個(gè)塊 readNextChunk(); } else { alert('Please select a file first!'); } }); </script> </body> </html>
- 由于文件讀取是異步操作,遞歸調(diào)用 readNextChunk() 在每塊數(shù)據(jù)處理完成后繼續(xù)下一塊處理。
2,使用 stream
使用 File API 的 stream()
方法(在較新的瀏覽器中支持),這允許你以流的方式讀取文件。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Stream Read File</title> </head> <body> <input type="file" id="fileInput"> <button id="processButton">Process File Stream</button> <script> document.getElementById('processButton').addEventListener('click', async function () { const fileInput = document.getElementById('fileInput'); const file = fileInput.files[0]; if (file) { const stream = file.stream(); const reader = stream.getReader(); // 讀取流數(shù)據(jù) async function read() { let result; while (!(result = await reader.read()).done) { const chunk = result.value; // Uint8Array const textChunk = new TextDecoder().decode(chunk); // 轉(zhuǎn)換為文本 console.log(textChunk); // 處理數(shù)據(jù)塊 } console.log("File processing complete."); } // 開始讀取 read().catch(error => console.error("Stream read error:", error)); } else { alert('Please select a file first!'); } }); </script> </body> </html>、
file.stream()
: 這是 File 對(duì)象的新方法,返回一個(gè) ReadableStream,用于讀取文件內(nèi)容。stream.getReader()
: 通過(guò)調(diào)用 stream.getReader() 獲取流的讀取器,返回 ReadableStreamDefaultReader 對(duì)象。reader.read()
: 每次調(diào)用 reader.read() 方法,讀取流中的一個(gè)塊數(shù)據(jù),返回一個(gè) Promise,該 Promise 解析為一個(gè)對(duì)象,包含done
和value
屬性。- done: 如果為 true,表示流已讀取完畢。
- value: 當(dāng)前讀取的數(shù)據(jù)塊,以 Uint8Array 的形式返回。
TextDecoder: 用于將 Uint8Array 數(shù)據(jù)塊轉(zhuǎn)換為可讀的文本。對(duì)于非文本數(shù)據(jù),可以根據(jù)需要進(jìn)行其他處理。
while 循環(huán): 通過(guò) while 循環(huán)不斷讀取文件流,直到流結(jié)束。
通過(guò)
async/await
和 Promises 實(shí)現(xiàn)簡(jiǎn)潔的異步文件讀取邏輯。
(三)前端代碼讀取本地文件需要注意的地方
1,安全性問(wèn)題
問(wèn)題: 瀏覽器出于安全考慮,限制了對(duì)用戶文件系統(tǒng)的直接訪問(wèn),以防止惡意腳本未經(jīng)用戶同意訪問(wèn)敏感文件或數(shù)據(jù)。前端代碼只能通過(guò)用戶明確選擇的方式訪問(wèn)文件,比如通過(guò) <input type="file">
或 File System Access API。
處理方法:
- 用戶明確選擇: 必須通過(guò)文件選擇對(duì)話框(如
<input type="file">
)讓用戶主動(dòng)選擇文件,而不是讓腳本直接訪問(wèn)。<input type="file" id="fileInput">
- 文件處理的權(quán)限: 使用 File System Access API(如
showOpenFilePicker()
)時(shí),瀏覽器會(huì)明確向用戶請(qǐng)求權(quán)限。確保只在必要時(shí)請(qǐng)求最少的權(quán)限。
async function selectFile() { const [fileHandle] = await window.showOpenFilePicker(); const file = await fileHandle.getFile(); console.log(file.name); }
- 保持權(quán)限范圍最小化: 只請(qǐng)求需要的文件或目錄,不嘗試訪問(wèn)整個(gè)文件系統(tǒng)。限制操作的范圍,例如只允許讀取,避免寫入或刪除操作。
2,隱私問(wèn)題
問(wèn)題: 用戶文件可能包含敏感信息,如個(gè)人數(shù)據(jù)、財(cái)務(wù)信息等。前端讀取文件時(shí),必須確保用戶的隱私不被泄露或?yàn)E用。
處理方法:
- 透明度: 明確告知用戶文件將被讀取的內(nèi)容和目的,避免在用戶不知情的情況下讀取數(shù)據(jù)。
- 本地處理: 盡量在本地處理文件內(nèi)容,避免將數(shù)據(jù)上傳到服務(wù)器或發(fā)送到第三方服務(wù),除非獲得用戶明確同意。
const reader = new FileReader(); reader.onload = function(e) { const content = e.target.result; // 只在本地處理數(shù)據(jù) }; reader.readAsText(file);
- 數(shù)據(jù)清理: 如果需要將文件內(nèi)容傳輸?shù)椒?wù)器,確保對(duì)敏感數(shù)據(jù)進(jìn)行加密,并在處理完畢后清理不再需要的數(shù)據(jù)。
3,性能問(wèn)題
題: 在前端處理大文件時(shí),可能會(huì)導(dǎo)致瀏覽器內(nèi)存占用過(guò)高或卡頓,影響用戶體驗(yàn)。
處理方法:
- 分塊處理: 對(duì)于大文件,使用 File API 的
slice()
方法或stream()
方法將文件分塊讀取,逐步處理文件內(nèi)容,避免一次性將整個(gè)文件加載到內(nèi)存中。const CHUNK_SIZE = 1024 * 1024; // 1MB let offset = 0; function readChunk(file) { const chunk = file.slice(offset, offset + CHUNK_SIZE); const reader = new FileReader(); reader.onload = function(e) { const content = e.target.result; console.log(content); // 處理數(shù)據(jù)塊 offset += CHUNK_SIZE; if (offset < file.size) { readChunk(file); // 繼續(xù)讀取下一塊 } }; reader.readAsText(chunk); }
- 異步操作: 使用 async/await 或 Promises 處理文件讀取,以避免阻塞主線程,確保頁(yè)面保持響應(yīng)性。
4,兼容性問(wèn)題
并非所有瀏覽器都支持最新的 File System Access API 或某些高級(jí)文件處理功能。需要確保代碼在多個(gè)瀏覽器中都能正常工作,或者提供合理的回退機(jī)制。
問(wèn)題: 并非所有瀏覽器都支持最新的 File System Access API 或某些高級(jí)文件處理功能。需要確保代碼在多個(gè)瀏覽器中都能正常工作,或者提供合理的回退機(jī)制。
處理方法:
- Feature Detection: 在使用某些文件 API 之前,檢查瀏覽器是否支持該功能。使用
if
語(yǔ)句檢查是否存在特定 API。if (window.showOpenFilePicker) { // 使用 File System Access API } else { // 回退到 <input type="file"> }
5,用戶體驗(yàn)問(wèn)題
問(wèn)題: 前端文件操作通常涉及用戶選擇文件、上傳文件、下載文件等操作,良好的用戶體驗(yàn)可以提升用戶的滿意度。
處理方法:
進(jìn)度指示: 在處理大文件時(shí),顯示進(jìn)度指示器(如進(jìn)度條),讓用戶了解文件處理進(jìn)度,避免用戶感覺應(yīng)用卡死。
<progress id="progressBar" value="0" max="100"></progress> // 在讀取文件塊時(shí)更新進(jìn)度條 progressBar.value = (offset / file.size) * 100;
錯(cuò)誤處理: 提供友好的錯(cuò)誤提示和處理機(jī)制,幫助用戶理解問(wèn)題并采取行動(dòng)(如重新選擇文件)。
reader.onerror = function(e) { alert('Error reading file: ' + e.target.error.message); };
反饋和確認(rèn): 當(dāng)文件操作成功完成時(shí),給用戶反饋,例如提示文件處理完畢,或確認(rèn)下載已完成。
6,權(quán)限管理問(wèn)題
問(wèn)題: 文件操作可能涉及權(quán)限問(wèn)題,例如通過(guò) File System Access API 訪問(wèn)文件系統(tǒng)時(shí),權(quán)限可能會(huì)被撤銷。
處理方法:
- 權(quán)限檢查: 每次操作前,檢查是否仍有權(quán)限訪問(wèn)文件或目錄。如果權(quán)限被撤銷,提示用戶重新授權(quán)。
const permission = await fileHandle.queryPermission(); if (permission !== 'granted') { // 提示用戶重新授權(quán) }
- 權(quán)限請(qǐng)求: 如果沒(méi)有權(quán)限,可以使用 requestPermission() 方法主動(dòng)請(qǐng)求權(quán)限。
const permission = await fileHandle.requestPermission(); if (permission === 'granted') { // 執(zhí)行文件操作 }
7,文件類型和內(nèi)容驗(yàn)證
問(wèn)題: 用戶可能會(huì)選擇錯(cuò)誤類型的文件,或上傳包含惡意內(nèi)容的文件。
處理方法:
文件類型過(guò)濾: 使用
<input type="file">
元素的accept
屬性限制用戶選擇的文件類型。例如,限制只選擇 .txt 文件。<input type="file" accept=".txt">
內(nèi)容驗(yàn)證: 在處理文件內(nèi)容之前,驗(yàn)證文件的實(shí)際內(nèi)容格式。例如,如果文件是 JSON 格式,可以嘗試解析內(nèi)容并捕獲錯(cuò)誤。
try { const data = JSON.parse(fileContent); } catch (e) { alert('Invalid JSON format'); }
8,文件大小限制
問(wèn)題: 處理非常大的文件可能會(huì)導(dǎo)致內(nèi)存溢出或性能問(wèn)題。
處理方法:
- 限制文件大小: 在前端代碼中設(shè)置文件大小限制,并在用戶選擇文件時(shí)進(jìn)行檢查。如果文件過(guò)大,給出提示。
const MAX_SIZE = 10 * 1024 * 1024; // 10MB if (file.size > MAX_SIZE) { alert('File is too large!'); return; }
這里舉個(gè)例子??:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>文件處理</title> </head> <body> <input type="file" id="fileInput" accept=".pdf"> <button id="processButton">Process</button> <progress id="progressBar" value="0" max="100" style="display: none;"></progress> <p id="percentage">0%</p> <p id="statusMessage"></p> <script> document.getElementById('processButton').addEventListener('click', function () { const fileInput = document.getElementById('fileInput'); const file = fileInput.files[0]; const MAX_SIZE = 300 * 1024 * 1024; // 最大300MB const progressBar = document.getElementById('progressBar'); const percentageDisplay = document.getElementById('percentage'); const statusMessage = document.getElementById('statusMessage'); // 重置狀態(tài) progressBar.style.display = 'none'; progressBar.value = 0; percentageDisplay.textContent = '0%'; statusMessage.textContent = ''; // 檢查是否選擇了文件 if (!file) { alert('Please select a file first!'); return; } // 檢查文件大小 if (file.size > MAX_SIZE) { alert('File is too large! Please select a file under 300MB.'); return; } console.log(`Selected file: ${file.name}, ${file.size} bytes, ${file.type}`); // // 檢查文件類型(假設(shè)只接受文本文件) // if (file.type !== "text/plain") { // alert('Invalid file type! Please select a .pdf file.'); // return; // } const CHUNK_SIZE = 1024 * 1024; // 1MB 分塊大小 let offset = 0; // 顯示進(jìn)度條 progressBar.style.display = 'block'; // 遞歸讀取文件的函數(shù) function readNextChunk() { // 檢查是否已經(jīng)讀取到文件末尾 if (offset >= file.size) { statusMessage.textContent = "File processing complete."; progressBar.style.display = 'none'; return; } // 讀取當(dāng)前塊 const chunk = file.slice(offset, offset + CHUNK_SIZE); const reader = new FileReader(); reader.onload = function (e) { // 處理當(dāng)前塊的數(shù)據(jù) let content = e.target.result; console.log(`Processing chunk from ${offset} to ${offset + CHUNK_SIZE}`); console.log(content); // 此處可以進(jìn)行更復(fù)雜的處理 // 更新偏移量,并讀取下一塊 offset += CHUNK_SIZE; // 計(jì)算百分比并更新顯示 const percentage = Math.min((offset / file.size) * 100, 100).toFixed(2); progressBar.value = percentage; percentageDisplay.textContent = `${percentage}%`; readNextChunk(); }; reader.onerror = function (e) { console.error("Error reading file chunk:", e); statusMessage.textContent = "Error reading file!"; progressBar.style.display = 'none'; }; // 開始讀取當(dāng)前塊 reader.readAsText(chunk); } // 開始讀取第一個(gè)塊 readNextChunk(); }); </script> </body> </html>
三,寫文件
在前端代碼中將信息寫入本地文件是一個(gè)常見的需求,但由于瀏覽器的安全限制,這個(gè)過(guò)程并不像在后端那樣直接。我們有幾種方法可以實(shí)現(xiàn)這個(gè)功能,每種方法都有其優(yōu)缺點(diǎn)。
(一)最常用的方法
最常用的方法時(shí)使用 Blob 和 URL.createObjectURL()
。
function saveToFile(content, filename) { const blob = new Blob([content], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = filename; // 這行是必要的,用于在瀏覽器中觸發(fā)下載 document.body.appendChild(link); link.click(); // 清理并移除鏈接 document.body.removeChild(link); URL.revokeObjectURL(url); } // 使用示例 saveToFile('Hello, World!', 'example.txt');
優(yōu)點(diǎn):
- 廣泛支持,適用于大多數(shù)現(xiàn)代瀏覽器。
- 可以處理大文件。
- 可以保存各種類型的數(shù)據(jù)(不僅僅是文本)。
缺點(diǎn):
- 用戶需要選擇保存位置,無(wú)法直接寫入特定位置。
- 不能追加內(nèi)容到現(xiàn)有文件。
(二)使用 File System Access API
這是一個(gè)較新的API,提供了更強(qiáng)大的文件操作能力,但目前只有部分現(xiàn)代瀏覽器支持。
async function writeToFile(content) { if ('showSaveFilePicker' in window) { try { const handle = await window.showSaveFilePicker({ types: [{ description: 'Text file', accept: { 'text/plain': ['.txt'] }, }], }); const writable = await handle.createWritable(); await writable.write(content); await writable.close(); console.log('File saved successfully'); } catch (err) { console.error('Error saving file:', err); } } else { console.error('File System Access API not supported'); } } // 使用示例 writeToFile('Hello, World!');
優(yōu)點(diǎn):
- 提供更強(qiáng)大的文件操作能力,包括讀取、寫入和修改文件。
- 可以訪問(wèn)用戶選擇的文件或目錄。
- 支持大文件和流式操作。
缺點(diǎn):
- 瀏覽器支持有限,主要是新版Chrome和Edge。
- 需要用戶明確授予權(quán)限。
(三)使用 LocalStorage 或 IndexedDB
這些方法不是直接將數(shù)據(jù)保存為文件,而是將數(shù)據(jù)存儲(chǔ)在瀏覽器的本地存儲(chǔ)中。
對(duì)于 LocalStorage:
function saveToLocalStorage(key, value) { localStorage.setItem(key, value); } // 使用示例 saveToLocalStorage('myData', 'Hello, World!');
對(duì)于 IndexedDB,代碼會(huì)相對(duì)復(fù)雜一些,這里是一個(gè)簡(jiǎn)化的例子:
let db; const dbName = "MyDatabase"; const request = indexedDB.open(dbName, 1); request.onerror = function(event) { console.error("Database error: " + event.target.error); }; request.onsuccess = function(event) { db = event.target.result; console.log("Database opened successfully"); }; request.onupgradeneeded = function(event) { db = event.target.result; const objectStore = db.createObjectStore("files", { keyPath: "id" }); }; function saveToIndexedDB(id, content) { const transaction = db.transaction(["files"], "readwrite"); const objectStore = transaction.objectStore("files"); const request = objectStore.put({ id: id, content: content }); request.onerror = function(event) { console.error("Error saving data: " + event.target.error); }; request.onsuccess = function(event) { console.log("Data saved successfully"); }; } // 使用示例(需要在數(shù)據(jù)庫(kù)打開后調(diào)用) saveToIndexedDB('file1', 'Hello, World!');
優(yōu)點(diǎn):
- 不需要用戶交互就能保存數(shù)據(jù)。
- 數(shù)據(jù)持久化存儲(chǔ)在瀏覽器中。
- 適用于存儲(chǔ)應(yīng)用程序狀態(tài)或小型數(shù)據(jù)集。
缺點(diǎn):
- 存儲(chǔ)容量有限(LocalStorage通常限制為5MB左右)。
- 數(shù)據(jù)只存儲(chǔ)在瀏覽器中,不是真正的文件。
- 用戶清除瀏覽器數(shù)據(jù)時(shí)會(huì)丟失。
一個(gè)完整的示例??:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>文件保存示例</title> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } textarea { width: 100%; height: 100px; margin-bottom: 10px; } button { margin-right: 10px; margin-bottom: 10px; } </style> </head> <body> <h1>文件保存示例</h1> <textarea id="content" placeholder="在此輸入要保存的內(nèi)容"></textarea> <div> <button onclick="saveUsingBlob()">使用Blob下載</button> <button onclick="saveUsingFileSystem()">使用File System API保存</button> <button onclick="saveToLocalStorage()">保存到LocalStorage</button> <button onclick="saveToIndexedDB()">保存到IndexedDB</button> </div> <div id="status"></div> <script> // 使用Blob和URL.createObjectURL()方法 function saveUsingBlob() { const content = document.getElementById('content').value; const blob = new Blob([content], {type: 'text/plain'}); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = 'example.txt'; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); updateStatus('文件已準(zhǔn)備下載'); } // 使用File System Access API async function saveUsingFileSystem() { const content = document.getElementById('content').value; if ('showSaveFilePicker' in window) { try { const handle = await window.showSaveFilePicker({ types: [{ description: 'Text file', accept: {'text/plain': ['.txt']}, }], }); const writable = await handle.createWritable(); await writable.write(content); await writable.close(); updateStatus('文件保存成功'); } catch (err) { updateStatus('保存文件時(shí)出錯(cuò): ' + err); } } else { updateStatus('此瀏覽器不支持File System Access API'); } } // 使用LocalStorage function saveToLocalStorage() { const content = document.getElementById('content').value; try { localStorage.setItem('savedContent', content); updateStatus('內(nèi)容已保存到LocalStorage'); } catch (err) { updateStatus('保存到LocalStorage時(shí)出錯(cuò): ' + err); } } // 使用IndexedDB let db; const dbName = "MyDatabase"; const dbVersion = 1; const request = indexedDB.open(dbName, dbVersion); request.onerror = function (event) { updateStatus("打開數(shù)據(jù)庫(kù)時(shí)出錯(cuò): " + event.target.error); }; request.onsuccess = function (event) { db = event.target.result; updateStatus("數(shù)據(jù)庫(kù)已成功打開"); }; request.onupgradeneeded = function (event) { db = event.target.result; const objectStore = db.createObjectStore("files", {keyPath: "id"}); updateStatus("數(shù)據(jù)庫(kù)已創(chuàng)建"); }; function saveToIndexedDB() { const content = document.getElementById('content').value; if (!db) { updateStatus("數(shù)據(jù)庫(kù)未準(zhǔn)備好"); return; } const transaction = db.transaction(["files"], "readwrite"); const objectStore = transaction.objectStore("files"); const request = objectStore.put({id: "file1", content: content}); request.onerror = function (event) { updateStatus("保存到IndexedDB時(shí)出錯(cuò): " + event.target.error); }; request.onsuccess = function (event) { updateStatus("內(nèi)容已成功保存到IndexedDB"); }; } function updateStatus(message) { document.getElementById('status').textContent = message; } </script> </body> </html>
總結(jié)
到此這篇關(guān)于JavaScript如何在前端代碼中讀、寫本地文件的文章就介紹到這了,更多相關(guān)JS讀寫本地文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
unicloud云開發(fā)進(jìn)階獲取首頁(yè)列表數(shù)據(jù)示例詳解
這篇文章主要為大家介紹了unicloud云開發(fā)進(jìn)階獲取首頁(yè)列表數(shù)據(jù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03JS事件循環(huán)-微任務(wù)-宏任務(wù)(原理講解+面試題分析)
這篇文章主要介紹了JS事件循環(huán)-微任務(wù)-宏任務(wù)的原理,本文章含有面試題分析,不管是面試者還是想要學(xué)習(xí)相關(guān)內(nèi)容的都可以很好的理解、掌握這部分內(nèi)容,需要的朋友可以參考下2023-01-01JSON創(chuàng)建鍵值對(duì)(key是中文或者數(shù)字)方式詳解
這篇文章主要介紹了JSON創(chuàng)建鍵值對(duì)(key是中文或者數(shù)字)方式詳解,需要的朋友可以參考下2017-08-08js實(shí)現(xiàn)下拉列表選中某個(gè)值的方法(3種方法)
這篇文章主要介紹了js實(shí)現(xiàn)下拉列表選中某個(gè)值的方法,涉及JavaScript針對(duì)select下拉列表選擇操作的相關(guān)技巧,需要的朋友可以參考下2015-12-12淺析Echarts圖表渲染導(dǎo)致內(nèi)存泄漏的原因及解決方案
在今年某個(gè)可視化大屏項(xiàng)目中,出現(xiàn)了一個(gè)問(wèn)題,項(xiàng)目在運(yùn)行一段時(shí)間后,頁(yè)面出現(xiàn)了崩潰,而且是大概運(yùn)行幾天之后,因?yàn)榇笃另?xiàng)目是部署到客戶現(xiàn)場(chǎng)大屏,長(zhǎng)時(shí)間運(yùn)行不關(guān)閉,小編認(rèn)為 Echarts 圖表渲染導(dǎo)致了內(nèi)存泄漏,本文將深入分析這一問(wèn)題,并提供解決方案2023-10-10js?實(shí)現(xiàn)picker?選擇器示例詳解
這篇文章主要為大家介紹了js?實(shí)現(xiàn)picker?選擇器示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10javascript使用正則表達(dá)式檢測(cè)IP地址
這篇文章主要介紹了javascript使用正則表達(dá)式檢測(cè)IP地址的方法,需要的朋友可以參考下2014-12-12