经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » JavaScript » 查看文章
JavaScript文件上传的常见问题整理
来源:jb51  时间:2022/6/27 16:57:46  对本文有异议

文件上传:<input type="file" /> (IE9及以下不支持下面这些功能,其它浏览器最新版本均已支持。)

1、允许上传文件数量

允许选择多个文件:

  1. <input type="file" multiple>

只允许上传一个文件:

  1. <input ?type="file" single>

2、上传指定的文件格式

  1. <input type="file" accept="image/gif,image/png" />

这里的上传格式仅指打开上传弹窗选择文件时默认的文件格式,可手动修改成其它文件格式。

如果不限制上传图片的格式可写成:accept="image/*"

其它格式参考如下:

*.3gpp   audio/3gpp, video/3gpp    3GPP Audio/Video
*.ac3    audio/ac3    AC3 Audio
*.asf    allpication/vnd.ms-asf    Advanced Streaming Format
*.au     audio/basic    AU Audio
*.css    text/css    Cascading Style Sheets
*.csv    text/csv    Comma Separated Values
*.doc    application/msword    MS Word Document
*.dot    application/msword    MS Word Template
*.dtd    application/xml-dtd    Document Type Definition
*.dwg    image/vnd.dwg    AutoCAD Drawing Database
*.dxf    image/vnd.dxf    AutoCAD Drawing Interchange Format
*.gif    image/gif    Graphic Interchange Format
*.htm    text/html    HyperText Markup Language
*.html   text/html    HyperText Markup Language
*.jp2    image/jp2    JPEG-2000
*.jpe    image/jpeg    JPEG
*.jpeg   image/jpeg    JPEG
*.jpg    image/jpeg    JPEG
*.js     text/javascript, application/javascript    JavaScript
*.json   application/json    JavaScript Object Notation
*.mp2    audio/mpeg, video/mpeg    MPEG Audio/Video Stream, Layer II
*.mp3    audio/mpeg    MPEG Audio Stream, Layer III
*.mp4    audio/mp4, video/mp4    MPEG-4 Audio/Video
*.mpeg   video/mpeg    MPEG Video Stream, Layer II
*.mpg    video/mpeg    MPEG Video Stream, Layer II
*.mpp    application/vnd.ms-project    MS Project Project
*.ogg    application/ogg, audio/ogg    Ogg Vorbis
*.pdf    application/pdf    Portable Document Format
*.png    image/png    Portable Network Graphics
*.pot    application/vnd.ms-powerpoint    MS PowerPoint Template
*.pps    application/vnd.ms-powerpoint    MS PowerPoint Slideshow
*.ppt    application/vnd.ms-powerpoint    MS PowerPoint Presentation
*.rtf    application/rtf, text/rtf    Rich Text Format
*.svf    image/vnd.svf    Simple Vector Format
*.tif    image/tiff    Tagged Image Format File
*.tiff   image/tiff    Tagged Image Format File
*.txt    text/plain    Plain Text
*.wdb    application/vnd.ms-works    MS Works Database
*.wps    application/vnd.ms-works    Works Text Document
*.xhtml  application/xhtml+xml    Extensible HyperText Markup Language
*.xlc    application/vnd.ms-excel    MS Excel Chart
*.xlm    application/vnd.ms-excel    MS Excel Macro
*.xls    application/vnd.ms-excel    MS Excel Spreadsheet
*.xlt    application/vnd.ms-excel    MS Excel Template
*.xlw    application/vnd.ms-excel    MS Excel Workspace
*.xml    text/xml, application/xml    Extensible Markup Language
*.zip    aplication/zip    Compressed Archive

3、FileList上传文件数组

FileList对象都是一组文件对象的集合,而文件对象则拥有下列的属性:
name – 文件名(不包含路径)
type – 文件的MIME类型(小写)
size – 文件的尺寸(单位为字节)

lastModifiedDate 为上传文件的最后修改时间

通过上面的几个对象,我们能够控制用户上传的文件大小和文件类型,以便减轻服务器再次检测时的压力,并提升安全系数

  1. var a=document.getElementById("file");
  2. a.onchange=function(e){
  3. e=e || window.event;
  4. var b=e.target.files;
  5. alert(b[0].name);
  6. }

4、拖动上传

dataTransfer 对象

dropEffect[=sCursorStyle]

设置或获取拖拽操作的类型和要显示的光标类型

  • copy:复制样式被显示
  • link:链接样式被显示
  • move:移动样式被显示
  • none:默认,没有鼠标样式被定义

effectAllowed[=sEffect]
设置或获取数据传送操作可应用与该对象的源元素

  • copy 选项被复制
  • link 选项被dataTransfer作为link方式保存
  • move 当放置时,对象被移动至目标对象
  • copylink 选项是被复制还是被作为link方式保存关键在于目标对象
  • linkmove 选项是被作为link方式保存还是被移动关键在于目标对象
  • all 所有效果都被支持
  • none 不支持任何效果
  • uninitialized 默认不能通过这个属性传递任何值

setData(sFormat,sData) 将指定格式的数据赋值给dataTransfer或者clipboardData sFormat:URL,Text
getData(sFormat) 从dataTransfer或者clipboardData中获取值 sFormat:URL,Text
clearData([sFormat]) 通过dataTransfer或者clipboardData中删除某种格式的数据 sFormat:Text,URL,File,HTML,Image

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. <style type="text/css">
  7. #DropZone{border:1px solid #CCC;height:50px;}
  8. </style>
  9. </head>
  10. <body>
  11. <input type="file" multiple accept="image/gif,image/png" id="file">
  12. <div id="DropZone"></div>
  13. <div id="Lists"></div>
  14. <script>
  15. var aa=document.getElementById("file");
  16. aa.onchange=function(){
  17. fileDrop();
  18. }
  19. function fileDrop(e) {
  20. e = e || window.event;
  21. e.stopPropagation(); // 阻止冒泡
  22. e.preventDefault(); //阻止默认行为
  23. var files = e.dataTransfer.files; //FileList
  24. var output = [];
  25. for(var i = 0, f; f = files[i]; i++) {
  26. output.push('<li><strong>' + f.name + '</strong>(' + f.type + ') - ' + f.size +' bytes</li>');
  27. }
  28. document.getElementById('Lists').innerHTML = '<ul>' + output.join('') + '</ul>';
  29. };
  30. function dragOver(e) {
  31. e = e || window.event;
  32. e.stopPropagation();
  33. e.preventDefault();
  34. e.dataTransfer.dropEffect = 'copy'; //指定拖放视觉效果
  35. };
  36. var d = document.getElementById('DropZone');
  37. try {
  38. d.addEventListener('dragover', dragOver, false);
  39. d.addEventListener('drop', fileDrop, false)
  40. } catch(ex) {
  41. document.write('something must be wrong!');
  42. }
  43. </script>
  44. </body>
  45. </html>

5、FileReader文件预览,读取文件数据(同时可读取图片文件宽高)

FileReader包含四种异步读取文件的方式:

  • FileReader.readAsBinaryString(Blob|File) - result属性包含的是file/blob的二进制字符串形式的数据。每个字节由一个0-255的整数表示。
  • FileReader.readAsText(Blob|File, opt_encoding) - result属性包含的是以文本方式表示的file/blob数据。默认情况下,字符串以'UTF-8'编码方式解码。使用opt_encoding参数可以指定一个不同的格式。
  • FileReader.readAsDataURL(Blob|File) - result属性包含的是以data URL编码的file/blob数据。
  • FileReader.readAsArrayBuffer(Blob|File) - result属性包含的是以ArrayBuffer对象表示的file/blob数据。

一旦这些read方法被调用,onloadstart, onprogress, onload, onabort, onerror, onloadend就可以被用来追踪进度。

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. <style type="text/css">
  7. body{margin:0;padding:0;}
  8. img{vertical-align:bottom;}
  9. </style>
  10. </head>
  11. <body>
  12. <input type="file" multiple accept="image/gif,image/png,,image/jpeg" id="Files">
  13. <div id="Preview"></div>
  14. <ul id="Errors"></ul>
  15. <script>
  16. function fileSelect(e) {
  17. e = e || window.event;
  18. var files = e.target.files; //FileList Objects
  19. var ireg = /image\/.*/i,
  20. p = document.getElementById('Preview');
  21. var ul = document.getElementById('Errors');
  22. for(var i = 0, f; f = files[i]; i++) {
  23. if(!f.type.match(ireg)) {
  24. //设置错误信息
  25. var li = document.createElement('li');
  26. li.innerHTML = '<li>' + f.name +'不是图片文件.</li>';
  27. ul.appendChild(li);
  28. continue;
  29. }
  30. var reader = new FileReader();
  31. reader.onload = (function(file) {
  32. return function(e) {
  33. var span = document.createElement('span');
  34. var img = new Image;
  35. img.alt=file.name;
  36. img.onload = function() {
  37. console.log(img.height); // image is loaded; sizes are available
  38. };
  39. img.src=this.result;
  40. span.innerHTML = '<img class="thumb" src="'+ this.result +'" alt="'+ file.name +'" />';
  41. p.insertBefore(span, null);
  42. };
  43. })(f);
  44. //读取文件内容
  45. reader.readAsDataURL(f);
  46. }
  47. }
  48. if(window.File && window.FileList && window.FileReader && window.Blob) {
  49. document.getElementById('Files').addEventListener('change', fileSelect, false);
  50. } else {
  51. document.write('您的浏览器不支持File Api');
  52. }
  53. </script>
  54. </body>
  55. </html>

上传txt文件内容预览(需对<>&'"|等符号进行过滤否则会中断读取):

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. <style type="text/css">
  7. body{margin:0;padding:0;}
  8. img{vertical-align:bottom;}
  9. </style>
  10. </head>
  11. <body>
  12. <input type="file" multiple id="Files">
  13. <div id="Preview"></div>
  14. <ul id="Errors"></ul>
  15. <script>
  16. function encodeHTML(source) {
  17. //return source;
  18. return source
  19. .replace(/&/g, '&')
  20. .replace(/</g, '<')
  21. .replace(/>/g, '>')
  22. .replace(/\"/g, '"');
  23. };
  24. function fileSelect(e) {
  25. e = e || window.event;
  26. var files = e.target.files; //FileList Objects
  27. var ireg = /text\/.*/i,
  28. p = document.getElementById('Preview');
  29. var ul = document.getElementById('Errors');
  30. for(var i = 0, f; f = files[i]; i++) {
  31. console.log(f.type);
  32. if(!f.type.match(ireg)) {
  33. //设置错误信息
  34. var li = document.createElement('li');
  35. li.innerHTML = '<li>' + f.name +'不是文本文件.</li>';
  36. ul.appendChild(li);
  37. continue;
  38. }
  39. var reader = new FileReader();
  40. reader.onload = (function(file) {
  41. return function(e) {
  42. var div = document.createElement('div');
  43. div.className = "text"
  44. div.innerHTML = encodeHTML(this.result);
  45. p.insertBefore(div, null);
  46. };
  47. })(f);
  48. //读取文件内容
  49. reader.readAsText(f);
  50. }
  51. }
  52. if(window.File && window.FileList && window.FileReader && window.Blob) {
  53. document.getElementById('Files').addEventListener('change', fileSelect, false);
  54. } else {
  55. document.write('您的浏览器不支持File Api');
  56. }
  57. </script>
  58. </body>
  59. </html>

读取上传txt指定区域文本内容:

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. <style type="text/css">
  7. body{margin:0;padding:0;}
  8. img{vertical-align:bottom;}
  9. </style>
  10. </head>
  11. <body>
  12. <input type="file" multiple id="Files">
  13. <button type="button" id="buttons" data-start="0" data-end="3">确定</button>
  14. <div id="range"></div>
  15. <div id="content"></div>
  16. <script>
  17. function readBlob(start, end) {
  18. var files = document.getElementById('Files').files;
  19. if(!files.length) {
  20. alert('请选择文件');
  21. return false;
  22. }
  23. var file = files[0],
  24. start = parseInt(start, 10) || 0,
  25. end = parseInt(end, 10) || (file.size - 1);
  26. var r = document.getElementById('range'),
  27. c = document.getElementById('content');
  28. var reader = new FileReader();
  29. reader.onloadend = function(e) {
  30. if(this.readyState == FileReader.DONE) {
  31. c.textContent = this.result;
  32. r.textContent = "Read bytes: " + (start + 1) + " - " + (end + 1) + " of " + file.size + " bytes";
  33. }
  34. };
  35. var blob;
  36. blob = file.slice(start, end + 1, 'text/plain;charset=UTF-8');
  37. reader.readAsBinaryString(blob);
  38. };
  39. try {
  40. document.getElementById('buttons').addEventListener('click', function(e) {
  41. if(e.target.tagName.toLowerCase() == 'button') {
  42. var start = e.target.getAttribute('data-start'),
  43. end = e.target.getAttribute('data-end');
  44. readBlob(start, end);
  45. }
  46. });
  47. } catch(ex) {
  48. alert('something error happens!')
  49. }
  50. </script>
  51. </body>
  52. </html>

File接口提供了slice方法支持把文件切成不同的片段,第一个参数是起始的字节数,第二个参数是结束的字节数,还有一个可选的内容类型字符串可以作为第三个参数。早期的chrome和firefox版本不支持file.slice 可使用file.webkitSlice和file.mozSlice替代,最新版本均支持file.slice。

6、文件读取进度

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. </head>
  7. <body>
  8. <form>
  9. <fieldset>
  10. <legend>分度读取文件:</legend>
  11. <input type="file" id="File" />
  12. <input type="button" value="中断" id="Abort" />
  13. <p>
  14. <label>读取进度:</label><progress id="Progress" value="0" max="100"></progress>
  15. </p>
  16. <p id="Status"></p>
  17. </fieldset>
  18. </form>
  19. <script>
  20. var h = {
  21. init: function() {
  22. var me = this;
  23. document.getElementById('File').onchange = me.fileHandler;
  24. document.getElementById('Abort').onclick = me.abortHandler;
  25. me.status = document.getElementById('Status');
  26. me.progress = document.getElementById('Progress');
  27. me.percent = document.getElementById('Percent');
  28. me.loaded = 0;
  29. //每次读取1M
  30. me.step = 1024 * 1024;
  31. me.times = 0;
  32. },
  33. fileHandler: function(e) {
  34. var me = h;
  35. var file = me.file = this.files[0];
  36. var reader = me.reader = new FileReader();
  37. //
  38. me.total = file.size;
  39. reader.onloadstart = me.onLoadStart;
  40. reader.onprogress = me.onProgress;
  41. reader.onabort = me.onAbort;
  42. reader.onerror = me.onerror;
  43. reader.onload = me.onLoad;
  44. reader.onloadend = me.onLoadEnd;
  45. //读取第一块
  46. me.readBlob(file, 0);
  47. },
  48. onLoadStart: function() {
  49. var me = h;
  50. },
  51. onProgress: function(e) {
  52. var me = h;
  53. me.loaded += e.loaded;
  54. //更新进度条
  55. me.progress.value = (me.loaded / me.total) * 100;
  56. },
  57. onAbort: function() {
  58. var me = h;
  59. },
  60. onError: function() {
  61. var me = h;
  62. },
  63. onLoad: function() {
  64. var me = h;
  65. if(me.loaded < me.total) {
  66. me.readBlob(me.loaded);
  67. } else {
  68. me.loaded = me.total;
  69. }
  70. },
  71. onLoadEnd: function() {
  72. var me = h;
  73. },
  74. readBlob: function(start) {
  75. var me = h;
  76. var blob,
  77. file = me.file;
  78. me.times += 1;
  79. if(file.slice) {
  80. blob = file.slice(start, start + me.step + 1);
  81. } else if(file.mozSlice) {
  82. blob = file.mozSlice(start, start + me.step + 1);
  83. }
  84. me.reader.readAsText(blob);
  85. },
  86. abortHandler: function() {
  87. var me = h;
  88. if(me.reader) {
  89. me.reader.abort();
  90. }
  91. }
  92. };
  93. h.init();
  94. </script>
  95. </body>
  96. </html>

本文代码以chrome测试为主。

到此这篇关于JavaScript文件上传问题整理的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号