JavaScript >> Javascript 文檔 >  >> JavaScript

在 JavaScript 中處理文件,第 1 部分:基礎知識

許多年前,我在谷歌的一次工作面試中被問到我會對網絡做出哪些改變以提供更好的體驗。在我的列表頂部,有一些方法可以處理 <input type="file"> 以外的文件 控制。即使網絡的其他部分在不斷發展,我們處理文件的方式自首次引入以來就從未改變過。值得慶幸的是,有了 HTML5 和相關 API,我們現在在最新版本的桌面瀏覽器中處理文件的選項比以往任何時候都多(iOS 仍然不支持 File API)。

文件類型

File 類型在 File API 中定義 1 規範,是文件的抽象表示。 File 的每個實例 有幾個屬性:

  • name – 文件名
  • size – 文件的大小(以字節為單位)
  • type – 文件的 MIME 類型

一個 File object 基本上為您提供有關文件的基本信息,而不提供對文件內容的直接訪問。這很重要,因為從文件讀取需要訪問磁盤,並且根據文件的大小,該過程可能會花費大量時間。 File object 只是對文件的引用,從該文件中獲取數據完全是一個單獨的過程。

獲取文件引用

當然,網絡上嚴格禁止訪問用戶文件,因為這是一個非常明顯的安全問題。你不會想加載一個網頁,然後讓它掃描你的硬盤並找出那裡有什麼。您需要獲得用戶的許可才能從他們的計算機訪問文件。但是,不需要混亂的權限窗口,因為用戶在決定上傳內容時始終授予網頁讀取文件的權限。

當您使用 <input type="file"> 控制,您正在授予網頁(和服務器)訪問該文件的權限。因此,您可以檢索 File 的第一個位置是有道理的 對像是通過 <input type="file"> 控制。

HTML5 定義了一個 files 所有 <input type="file"> 的屬性 控制。這個集合是一個 FileList ,這是一個類似數組的結構,稱為 FileList 包含 File 控件中每個選定文件的對象(請記住,HTML5 允許在這些控件中選擇多個文件)。因此,在任何時候,您都可以使用類似以下的代碼訪問用戶選擇的文件:

<input type="file" id="your-files" multiple>
<script>
var control = document.getElementById("your-files");
control.addEventListener("change", function(event) {

    // When the control has changed, there are new files

    var i = 0,
        files = control.files,
        len = files.length;

    for (; i < len; i++) {
        console.log("Filename: " + files[i].name);
        console.log("Type: " + files[i].type);
        console.log("Size: " + files[i].size + " bytes");
    }

}, false);
</script></code>

這個相對簡單的代碼監聽 change 文件控件上的事件。當事件觸發時,表示文件選擇發生了變化,代碼會遍歷每個File 對象並輸出其信息。請記住,files 屬性始終可以從 JavaScript 訪問,因此您不必等待 change 嘗試閱讀它。

拖放文件

從表單控件訪問文件仍然需要表單控件和相關的用戶瀏覽操作來查找感興趣的文件。幸運的是,HTML5 拖放 2 為用戶授予對其文件的訪問權限的另一種方式:只需將文件從桌面拖到 Web 瀏覽器中即可。你所要做的就是監聽兩個事件。

為了讀取拖放到頁面某個區域的文件,您必須監聽 dragoverdrop 事件並取消兩者的默認操作。這樣做會告訴瀏覽器您正在直接處理該操作,並且它不應該打開圖像文件。

<div id="your-files"></div>
<script>
var target = document.getElementById("your-files");

target.addEventListener("dragover", function(event) {
    event.preventDefault();
}, false);

target.addEventListener("drop", function(event) {

    // cancel default actions
    event.preventDefault();

    var i = 0,
        files = event.dataTransfer.files,
        len = files.length;

    for (; i < len; i++) {
        console.log("Filename: " + files[i].name);
        console.log("Type: " + files[i].type);
        console.log("Size: " + files[i].size + " bytes");
    }

}, false);
</script></code>

event.dataTransfer.files 是另一個FileList 您可以訪問以獲取文件信息的對象。代碼與使用文件表單控件和File幾乎一模一樣 對象可以用同樣的方式訪問。

Ajax 文件上傳

一旦你有了對文件的引用,你就可以做一些很酷的事情:通過 Ajax 上傳文件。由於 FormData,這一切皆有可能 對象,在 XMLHttpRequest Level 2 中定義 3 .該對象表示一個 HTML 表單,允許您添加鍵值對以通過 append() 提交給服務器 方法:

var form = new FormData();
form.append("name", "Nicholas");

FormData 的優點 對像是您可以直接向其添加文件,有效地模仿通過 HTML 表單上傳文件。您所要做的就是添加 File 使用特定名稱進行引用,其餘的由瀏覽器完成。例如:

// create a form with a couple of values
var form = new FormData();
form.append("name", "Nicholas");
form.append("photo", control.files[0]);

// send via XHR - look ma, no headers being set!
var xhr = new XMLHttpRequest();
xhr.onload = function() {
    console.log("Upload complete.");
};
xhr.open("post", "/entrypoint", true);
xhr.send(form);

一旦 FormData 對像被傳入 send() ,會自動為您設置正確的 HTTP 標頭。您不必擔心在使用文件時設置正確的表單編碼,因此服務器會像提交常規 HTML 表單一樣,從“照片”鍵讀取文件數據,從“名稱”讀取文本數據鑰匙。這使您可以自由地在後端編寫處理代碼,這些代碼可以輕鬆地處理傳統的 HTML 表單和這種性質的 Ajax 表單。

所有這些都適用於每個瀏覽器的最新版本,包括 Internet Explorer 10。

下一個

你現在知道了訪問 File 的兩種方法 瀏覽器中的信息:通過文件上傳控件和本地拖放。將來可能會有其他訪問文件的方法,但就目前而言,這是您需要知道的兩種。當然,閱讀有關文件的信息只是問題的一部分。下一步是從這些文件中讀取數據,這就是第 2 部分的重點。

參考

  1. 文件 API 規範(編輯草案)
  2. HTML5 拖放
  3. XMLHttpRequest 級別 2

Tutorial JavaScript 教程
  1. 如何在 Javascript 中檢查數組是否為空或為空

  2. 我們去兔子洞!

  3. 2020 年 21 大 Web 開發趨勢

  4. 嘗試...抓住...最終在 JavaScript 中

  5. jquery和jquery UI有什麼區別?

  6. 什麼是 React 道具?

  7. 可以為每個單元格設置 Tabulator 自動完成功能嗎?不是專欄?

  1. IDOM - Python 中的服務器端渲染

  2. ShareJS 0.7.3 工作示例

  3. 我學習編程概念的方法——什麼時候,為什麼?

  4. React 表單:使用 Refs

  5. 快速渲染 HTML

  6. 是否可以在 javascript 中創建弱引用?

  7. jQuery從選擇中刪除選項

  1. 如何為初學者 Dockerize 一個 Next.js 應用程序。

  2. 我的投資組合網站。

  3. 如何使用 OAuth 2.0 驗證和訪問 Google API

  4. 10 個 JavaScript 對話框/窗口教程