整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          「JS進階」 HTML5 之文件操作(file)

          在 HTML 文檔中 <input type="file"> 標簽每出現一次,一個 FileUpload 對象就會被創建。

          該元素包含一個文本輸入字段,用來輸入文件名,還有一個按鈕,用來打開文件選擇對話框以便圖形化選擇文件。

          該元素的 value 屬性保存了用戶指定的文件的名稱,但是當包含一個 file-upload 元素的表單被提交的時候,瀏覽器會向服務器發送選中的文件的內容而不僅僅是發送文件名。

          當用戶選擇或編輯一個文件名,file-upload 元素觸發 onchange 事件句柄。

          看個簡單例子:

          [html]view plaincopy

          <!--?oscar999??-->??
          <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">??
          <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);??
          ????}??
          ??}??
          ??</script>??
          ??</head>??
          ??<body>??
          ??<input?type="file"?id="file"?onchange="handleFiles(this.files)"/>??
          ??<div?id="filecontent"></div>??
          ??</body>??
          </html>??

          這里讀取一個文件, 顯示在div 中。

          (在IE8 中 無效, this.files 無法讀取文件。這個屬于HTML5 的特性)

          當選擇了一個文件時,就會把包含這個文件的列表(一個FileList對象)作為參數傳給handleFiles()函數了。這個FileList對象類似一個數組,可以知道文件的數目,而它的元素就是File對象了。從這個File對象可以獲取name、size、lastModifiedDate和type等屬性。把這個File對象傳給FileReader對象的讀取方法,就能讀取文件了。



          HTML5 Drag and Drop File

          Html5 支持的File 的操作不僅僅是文件的選擇,

          在HTML5 之前需要使用 Applet 和 SilverLight 才能達到的文件拖拽功能,在HTML5 中也能輕松的實現,

          看代碼:

          [html]view plaincopy

          <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">??
          <html>??
          ??<head>??
          ??<meta?http-equiv="content-type"?content="text/html;?charset=utf-8">??
          ??<meta?name="author"?content="oscar999">??
          ??<title></title>??
          ??</head>??
          ??<body>??
          ????<div?id="dropbox">?Drop?Here?</div>??
          ????<div?id="filecontent"></div>??
          ????<script>??
          ??????var?dropbox?=?document.getElementById("dropbox");????
          ??????dropbox.addEventListener("dragenter",?dragenter,?false);????
          ??????dropbox.addEventListener("dragover",?dragover,?false);????
          ??????dropbox.addEventListener("drop",?drop,?false);?????
          ????function?dragenter(e)?{????
          ????????e.stopPropagation();????
          ????????e.preventDefault();????
          ????}????
          ????function?dragover(e)?{????
          ????????e.stopPropagation();????
          ????????e.preventDefault();????
          ????}??
          ????function?drop(e)?{????
          ????????e.stopPropagation();????
          ????????e.preventDefault();?????
          ????????var?dt?=?e.dataTransfer;????
          ????????var?files?=?dt.files;??
          ????????if(files.length)??
          ????????{??
          ???????????var?file?=?files[0];??
          ???????????var?reader?=?new?FileReader();??
          ???????????reader.onload?=?function()??
          ???????????{??
          ???????????????document.getElementById("filecontent").innerHTML?=?this.result;??
          ???????????};??
          ???????????reader.readAsText(file);??
          ????????}??
          ????}???
          ????</script>??
          ??</body>??
          </html>??

          這里通過事件對象的 dataTransfer 可以得到文件。



          讀取文件內容

          在第一個例子中, 我們使用 FileReader類來讀取文件的內容,

          在 W3C 草案中,File 對象只包含文件名,文件類型等只讀屬性;FileReader用于內容讀取和監控讀取狀態。

          (在firefox 中, 可以直接使用 var fileBinary = file.getAsBinary(); 讀取文件的二進制源碼)

          FileReader提供的方法包括:

          1. readAsBinaryString

          2. readAsDataURL

          3. readAsText

          4. abort

          .........


          以下,舉一個 使用 FileReader 將用戶選擇的圖片不通過后臺即時顯示出來的例子。

          [html]view plaincopy

          function?handleFiles(files){??
          ????for?(var?i?=?0;?i?<?files.length;?i++)?{??
          ????????var?file?=?files[i];??
          ????????var?imageType?=?/image.*/;??
          ????????if?(!file.type.match(imageType))?{??
          ????????????continue;??
          ????????}??
          ????????var?img?=?document.createElement("img");??
          ????????img.classList.add("obj");??
          ????????img.file?=?file;??
          ????????preview.appendChild(img);??
          ????????var?reader?=?new?FileReader();??
          ????????reader.onload?=?(function(aImg){??
          ????????????return?function(e){??
          ????????????????aImg.src?=?e.target.result;??
          ????????????};??
          ????????})(img);??
          ????????reader.readAsDataURL(file);??
          ????}??
          }??



          同后端的交互

          在一般的HTML 中,使用方式是把file input 放在form 中, 以POST 方式把文件傳遞到后端。

          在 HTML5 中, 也可以通過 FileReader 的 readAsBinaryString 方法讀取到文件的二進制碼,然后通過 XMLHttpRequest 的 sendAsBinary 方法將其發送出去。

          [javascript]view plaincopy

          var?xhr?=?new?XMLHttpRequest();??
          xhr.open("POST",?"url");??
          xhr.overrideMimeType('text/plain;?charset=x-user-defined-binary');??
          <pre?code_snippet_id="422893"?snippet_file_name="blog_20140709_4_2106578"?class="sh_javascript?sh_sourceCode"?name="code">xhr<span?class="sh_symbol">.</span><span?class="sh_function">sendAsBinary</span><span?class="sh_symbol">(</span>binaryString<span?class="sh_symbol">);</span></pre><br> ?

          ileAPI

          介紹

          HTML5 為我們提供了 File API 相關規范。主要涉及 File 接口 和 FileReader 對象 。

          本文整理了兼容性檢測、文件選擇、屬性讀取、文件讀取、進度監控、大文件分片上傳以及拖拽上傳等開發中常見的前端文件操作。

          準備工作

          首先,我們的 File 來自于 <input> 標簽中選中的文件列表。所以,準備如下的 HTML 代碼:

          <input type="file" id="files" multiple />
          <div id="list"></div>
          <div id="images"></div>
          <!-- File API相關操作寫在了script.js中 -->
          <script src="./script.js"></script>
          

          檢測兼容性

          File 對象是特殊類型的 Blob。在 script 入口處,應該檢測當前瀏覽器是否支持 File API

          if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
           throw new Error("當前瀏覽器對FileAPI的支持不完善");
          }
          

          監聽文件選擇

          對于 typefile 類型的 <input> 標簽,在選擇文件的時候,會觸發 change 事件。用戶選中的文件信息也會傳入回調函數的第一個參數中。

          function handleFileSelect(event) {
           const { files } = event.target;
           if (!files.length) {
           console.log("沒有選擇文件");
           return;
           }
           console.log("選中的文件信息是:", files);
          }
          document
           .querySelector("#files")
           .addEventListener("change", handleFileSelect, false);
          

          文件屬性-File

          event.target.files 是一個 FileList 對象,它是一個由 File 對象組成的列表。

          每個 File 對象,保存著選中的對應文件的屬性。常用的用:

          • name:文件名
          • type:文件類型
          • size:文件大小

          下面,通過 type 屬性,過濾掉非圖片類型的文件,只展示圖片類型文件的信息:

          function handleFileSelect(event) {
           const { files } = event.target;
           if (!files.length) {
           console.log("沒有選擇文件");
           return;
           }
           const innerHTML = [];
           const reImage = /image.*/;
           for (let file of files) {
           if (!reImage.test(file.type)) {
           continue;
           }
           innerHTML.push(
           `
           <li>
           <strong>${file.name}</strong>
           (${file.type || "n/a"}) -
           ${file.size} bytes
           </li>
           `
           );
           }
           document.querySelector("#list").innerHTML = `<ul>${innerHTML.join("")}</ul>`;
          }
          

          FileReader

          讀取文件-FileReader

          還是以圖片讀取為例,讀取并且顯示所有的圖片類型文件。

          文件讀取需要使用 FileReader 對象,它常用 3 個回調方法:

          • onload: 文件讀取完成
          • onloadstart:文件上傳開始
          • onprogress : 文件上傳中觸發

          和Image類似,在讀取文件之前,需要先綁定事件處理。它讀取操作有:readAsArrayBuffer、readAsDataURLreadAsBinaryString、readAsText。傳入的參數就是 File 對象。

          那么這幾個方法有什么區別呢?不同的讀取方式,回調事件onload接受到的event.target.result不相同。比如,readAsDataURL 讀取的話,result 是一個圖片的 url。

          下面就是讀取圖片文件,然后展示的一個例子:

          function handleFileSelect(event) {
           let { files } = event.target;
           if (!files.length) {
           return;
           }
           let vm = document.createDocumentFragment(),
           re = /image.*/,
           loaded = 0, // 完成加載的圖片數量
           total = 0; // 總共圖片數量
           // 統計image文件數量
           for (let file of files) {
           re.test(file.type) && total++;
           }
           // onloadstart回調
           const handleLoadStart = (ev, file) =>
           console.log(`>>> Start load ${file.name}`);
           // onload回調
           const handleOnload = (ev, file) => {
           console.log(`<<< End load ${file.name}`);
           const img = document.createElement("img");
           img.height = 250;
           img.width = 250;
           img.src = ev.target.result;
           vm.appendChild(img);
           // 完成加載后,將其放入dom元素中
           if (++loaded === total) {
           document.querySelector("#images").appendChild(vm);
           }
           };
           for (let file of files) {
           if (!re.test(file.type)) {
           continue;
           }
           const reader = new FileReader();
           reader.onloadstart = ev => handleLoadStart(ev, file);
           reader.onload = ev => handleOnload(ev, file);
           // 讀取文件對象
           reader.readAsDataURL(file);
           }
          }
          document
           .querySelector("#files")
           .addEventListener("change", handleFileSelect, false);
          

          監控讀取進度

          在監控讀取進度的時候,主要是處理 FileReader 對象上的 onprogress 事件。

          下面的例子,請打開一個較大的文件來查看效果(否則一下就讀取完了):

          function handleFileSelect(event) {
           let { files } = event.target;
           if (!files.length) {
           return;
           }
           const handleLoadStart = (ev, file) =>
           console.log(`>>> Start load ${file.name}`);
           const handleProgress = (ev, file) => {
           if (!ev.lengthComputable) {
           return;
           }
           // 計算進度,并且以百分比形式展示
           const percent = Math.round((ev.loaded / ev.total) * 100);
           console.log(`<<< Loding ${file.name}, progress is ${percent}%`);
           };
           for (let file of files) {
           const reader = new FileReader();
           reader.onloadstart = ev => handleLoadStart(ev, file);
           reader.onprogress = ev => handleProgress(ev, file);
           reader.readAsArrayBuffer(file);
           }
          }
          document
           .querySelector("#files")
           .addEventListener("change", handleFileSelect, false);
          

          slice

          大文件分片讀取

          在對于超大文件,一般采用分片上傳的思路解決。文章開頭有講到,FileBlob 的一個特例。而 Blob 上有一個 slice (https://developer.mozilla.org/zh-CN/docs/Web/API/Blob/slice)方法,通過它,前端就可以實現分片讀取大文件的操作。

          為了方便說明,請先準備好一個 txt 文件,文件內容就是:hello world。

          示例代碼如下,代碼中只讀取前 5 個字節,由于每個英文字母占 1 個字節,所以打印結果應該是“hello”。

          function handleFileSelect(event) {
           let { files } = event.target;
           if (!files.length) {
           return;
           }
           // 為了方便說明,這里僅僅讀取第一個文件
           const file = files[0];
           // 讀取前5個字節的內容
           const blob = file.slice(0, 5);
           const reader = new FileReader();
           // 控制臺輸出結果應該是:hello
           reader.onload = ev => console.log(ev.target.result);
           reader.readAsText(blob);
          }
          document
           .querySelector("#files")
           .addEventListener("change", handleFileSelect, false);
          

          拖拽上傳

          和前面所述的 File API 相關是完全一樣的。唯一需要特殊處理的是文件對象的獲取入口改變了。對于 <input> 標簽,監聽 onchange 事件,FileList 存放在 event.target.files 中;對于拖拽操作,FileList 存放在拖拽事件的回調函數參數里,通過 event.dataTransfer.files 訪問即可。

          需要修改一下 html 代碼:

          <!DOCTYPE html>
          <head>
           <meta charset="UTF-8">
           <style>
           #container {
           width: 300px;
           height: 300px;
           border: 3px dotted red;
           }
           </style>
          </head>
          <body>
           <div id="container"></div>
           <script src="./script.js"></script>
          </body>
          </html>
          

          腳本文件的代碼如下:

          function handleDropover(event) {
           event.stopPropagation();
           event.preventDefault();
          }
          function handleDrop(event) {
           event.stopPropagation();
           event.preventDefault();
           /***** 訪問拖拽文件 *****/
           const files = event.dataTransfer.files;
           console.log(files);
           /**********/
          }
          const target = document.querySelector("#container");
          target.addEventListener("dragover", handleDropover);
          target.addEventListener("drop", handleDrop);
          

          后端相關

          后端相關超出了本文的討論范圍,可以參考這篇文章(https://github.com/purplebamboo/blog/issues/17)。

          版權

          作者:心譚

          鏈接:https://juejin.im/post/5d35af63e51d454fa33b199e

          著作權歸作者所有。

          關注

          感謝閱讀,如果這篇文章對你又幫助,記得 點贊 ,收藏轉發 喲。

          期待下次與你相遇 :)

          tml5超大文件上傳和斷點續傳的實現,html5超大文件上傳的實現,html5超大文件上傳解決方案,html5超大文件上傳思路,html5超大文件上傳實例,html5超大文件上傳源碼,html5超大文件分片上傳,html5超大文件分塊上傳,html5超大文件加密上傳,html5文件夾上傳,


          要求操作便利,一次選擇多個文件和文件夾進行上傳;

          支持PC端全平臺操作系統,Windows,Linux,Mac

          支持文件和文件夾的批量下載,斷點續傳。刷新頁面后繼續傳輸。關閉瀏覽器后保留進度信息。

          支持文件夾批量上傳下載,服務器端保留文件夾層級結構,服務器端文件夾層級結構與本地相同。

          支持大文件批量上傳(20G)和下載,同時需要保證上傳期間用戶電腦不出現卡死等體驗;

          支持文件夾上傳,文件夾中的文件數量達到1萬個以上,且包含層級結構。

          支持斷點續傳,關閉瀏覽器或刷新瀏覽器后仍然能夠保留進度。

          支持文件夾結構管理,支持新建文件夾,支持文件夾目錄導航

          交互友好,能夠及時反饋上傳的進度;

          服務端的安全性,不因上傳文件功能導致JVM內存溢出影響其他功能使用;

          最大限度利用網絡上行帶寬,提高上傳速度;

          對于大文件的處理,無論是用戶端還是服務端,如果一次性進行讀取發送、接收都是不可取,很容易導致內存問題。所以對于大文件上傳,采用切塊分段上傳

          從上傳的效率來看,利用多線程并發上傳能夠達到最大效率。

          文件上傳頁面的前端可以選擇使用一些比較好用的上傳組件,例如百度的開源組件WebUploader,這些組件基本能滿足文件上傳的一些日常所需功能,如異步上傳文件,文件夾,拖拽式上傳,黏貼上傳,上傳進度監控,文件縮略圖,甚至是大文件斷點續傳,大文件秒傳。

          在web項目中上傳文件夾現在已經成為了一個主流的需求。在OA,或者企業ERP系統中都有類似的需求。上傳文件夾并且保留層級結構能夠對用戶行成很好的引導,用戶使用起來也更方便。能夠提供更高級的應用支撐。


          下載示例:

          https://gitee.com/xproer/up6-jsp-eclipse/tree/6.5.40/




          工程



          NOSQL

          NOSQL示例不需要任何配置,可以直接訪問測試



          創建數據表

          選擇對應的數據表腳本,這里以SQL為例




          修改數據庫連接信息


          訪問頁面進行測試



          文件存儲路徑

          up6/upload/年/月/日/guid/filename






          相關問題:
          1.javax.servlet.http.HttpServlet錯誤
          2.項目無法發布到tomcat
          3.md5計算完畢后卡住
          4.服務器找不到config.json文件

          相關參考:

          文件保存位置


          源碼工程文檔:https://drive.weixin.qq.com/s?k=ACoAYgezAAw1dWofra

          源碼報價單:https://drive.weixin.qq.com/s?k=ACoAYgezAAwoiul8gl



          OEM版報價單:https://drive.weixin.qq.com/s?k=ACoAYgezAAwuzp4W0a

          產品源代碼:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc
          授權生成器:https://drive.weixin.qq.com/s?k=ACoAYgezAAwTIcFph1


          主站蜘蛛池模板: 亚洲乱码国产一区三区| 国产精品视频免费一区二区三区 | 一区二区不卡久久精品| 久久久久人妻精品一区三寸| 日韩精品无码一区二区三区| 亚洲天堂一区在线| 麻豆va一区二区三区久久浪| 国产福利视频一区二区| 亚洲一区二区三区无码影院| 在线观看国产一区| 一区二区乱子伦在线播放| 日本不卡一区二区视频a| 国产日韩一区二区三区| 国精产品一区一区三区有限在线| 国产精品亚洲专区一区| 中文字幕在线精品视频入口一区| 久久精品岛国av一区二区无码| 国产精品夜色一区二区三区| 日韩精品无码久久一区二区三| 亚洲国产综合精品一区在线播放| 亚洲国产成人一区二区精品区 | 国产乱码一区二区三区四| 丝袜美腿一区二区三区| 国产一区中文字幕在线观看| 无码AV天堂一区二区三区| AV天堂午夜精品一区二区三区| 风间由美性色一区二区三区 | 日美欧韩一区二去三区| 亚洲一区二区三区自拍公司| 国产一区二区草草影院| 99久久人妻精品免费一区 | 久久久久成人精品一区二区| 国产一区在线视频观看| 国产精品视频一区二区三区经 | 一区二区三区午夜视频| 综合激情区视频一区视频二区| 亚洲熟女综合一区二区三区| 男插女高潮一区二区| 无码人妻精品一区二区在线视频 | 日本精品视频一区二区| 亚洲一区精彩视频|