JavaScript文件上传的常见问题整理

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

1、允许上传文件数量

允许选择多个文件:

<input type="file" multiple>

只允许上传一个文件:

<input  type="file" single>

2、上传指定的文件格式

<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 为上传文件的最后修改时间

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

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

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

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#DropZone{border:1px solid #CCC;height:50px;}
</style>
</head>
<body>
<input type="file" multiple accept="image/gif,image/png" id="file">
<div id="DropZone"></div>
<div id="Lists"></div>
<script>
var aa=document.getElementById("file");
aa.onchange=function(){
    fileDrop();
}

function fileDrop(e) {
    e = e || window.event;

    e.stopPropagation(); // 阻止冒泡
    e.preventDefault();  //阻止默认行为

    var files = e.dataTransfer.files;   //FileList

    var output = [];

    for(var i = 0, f; f = files[i]; i++) {
        output.push('<li><strong>' + f.name + '</strong>(' + f.type + ') - ' + f.size +' bytes</li>');
    }

    document.getElementById('Lists').innerHTML = '<ul>' + output.join('') + '</ul>';
};

function dragOver(e) {
    e = e || window.event;

    e.stopPropagation();
    e.preventDefault();
    e.dataTransfer.dropEffect = 'copy'; //指定拖放视觉效果
};
var d = document.getElementById('DropZone');

try {
    d.addEventListener('dragover', dragOver, false);
    d.addEventListener('drop', fileDrop, false)
} catch(ex) {
    document.write('something must be wrong!');
}

</script>
</body>
</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就可以被用来追踪进度。

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
body{margin:0;padding:0;}
img{vertical-align:bottom;}
</style>
</head>
<body>
<input type="file" multiple accept="image/gif,image/png,,image/jpeg" id="Files">
<div id="Preview"></div>
<ul id="Errors"></ul>
<script>
function fileSelect(e) {
    e = e || window.event;

    var files = e.target.files;  //FileList Objects
    var ireg = /image\/.*/i,
        p = document.getElementById('Preview');

    var ul = document.getElementById('Errors');
    for(var i = 0, f; f = files[i]; i++) {
        if(!f.type.match(ireg)) {
            //设置错误信息
            var li = document.createElement('li');
            li.innerHTML = '<li>' + f.name +'不是图片文件.</li>';

            ul.appendChild(li);

            continue;
        }

        var reader = new FileReader();

        reader.onload = (function(file) {
            return function(e) {
                var span = document.createElement('span');
                var img = new Image;
                img.alt=file.name;
                img.onload = function() {
                    console.log(img.height); // image is loaded; sizes are available
                };

                img.src=this.result;
                span.innerHTML = '<img class="thumb" src="'+ this.result +'" alt="'+ file.name +'" />';

                p.insertBefore(span, null);
            };
        })(f);
        //读取文件内容
        reader.readAsDataURL(f);
    }
}

if(window.File && window.FileList && window.FileReader && window.Blob) {
    document.getElementById('Files').addEventListener('change', fileSelect, false);
} else {
    document.write('您的浏览器不支持File Api');
}
</script>
</body>
</html>

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

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
body{margin:0;padding:0;}
img{vertical-align:bottom;}
</style>
</head>
<body>
<input type="file" multiple id="Files">
<div id="Preview"></div>
<ul id="Errors"></ul>
<script>
function encodeHTML(source) {
    //return source;
    return source
            .replace(/&/g, '&')
            .replace(/</g, '<')
            .replace(/>/g, '>')
            .replace(/\"/g, '"');
};
function fileSelect(e) {
    e = e || window.event; 

    var files = e.target.files;  //FileList Objects
    var ireg = /text\/.*/i,
        p = document.getElementById('Preview'); 

    var ul = document.getElementById('Errors');
    for(var i = 0, f; f = files[i]; i++) {
        console.log(f.type);
        if(!f.type.match(ireg)) {
            //设置错误信息
            var li = document.createElement('li');
            li.innerHTML = '<li>' + f.name +'不是文本文件.</li>'; 

            ul.appendChild(li); 

            continue;
        } 

        var reader = new FileReader(); 

        reader.onload = (function(file) {
            return function(e) {
                var div = document.createElement('div');
                div.className = "text"
                div.innerHTML = encodeHTML(this.result); 

                p.insertBefore(div, null);
            };
        })(f);
        //读取文件内容
        reader.readAsText(f);
    }
} 

if(window.File && window.FileList && window.FileReader && window.Blob) {
    document.getElementById('Files').addEventListener('change', fileSelect, false);
} else {
    document.write('您的浏览器不支持File Api');
}
</script>
</body>
</html>

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

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
body{margin:0;padding:0;}
img{vertical-align:bottom;}
</style>
</head>
<body>
<input type="file" multiple id="Files">
<button type="button" id="buttons" data-start="0" data-end="3">确定</button>
<div id="range"></div>
<div id="content"></div>
<script>

function readBlob(start, end) {
    var files = document.getElementById('Files').files; 

    if(!files.length) {
        alert('请选择文件');
        return false;
    } 

    var file = files[0],
        start = parseInt(start, 10) || 0,
        end = parseInt(end, 10) || (file.size - 1); 

    var r = document.getElementById('range'),
        c = document.getElementById('content'); 

    var reader = new FileReader(); 

    reader.onloadend = function(e) {
        if(this.readyState == FileReader.DONE) {
            c.textContent = this.result;
            r.textContent = "Read bytes: " + (start + 1) + " - " + (end + 1) + " of " + file.size + " bytes";
        }
    }; 

    var blob; 

    blob = file.slice(start, end + 1, 'text/plain;charset=UTF-8');
    reader.readAsBinaryString(blob);
}; 

try {
    document.getElementById('buttons').addEventListener('click', function(e) {
        if(e.target.tagName.toLowerCase() == 'button') {
            var start = e.target.getAttribute('data-start'),
                end = e.target.getAttribute('data-end'); 

            readBlob(start, end);
        }
    });
} catch(ex) {
    alert('something error happens!')
}
</script>
</body>
</html>

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

6、文件读取进度

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form>
    <fieldset>
        <legend>分度读取文件:</legend>
        <input type="file" id="File" />
        <input type="button" value="中断" id="Abort" />
        <p>
            <label>读取进度:</label><progress id="Progress" value="0" max="100"></progress>
        </p>
        <p id="Status"></p>
    </fieldset>
</form> 

<script>
var h = {
    init: function() {
        var me = this; 

        document.getElementById('File').onchange = me.fileHandler;
        document.getElementById('Abort').onclick = me.abortHandler; 

        me.status = document.getElementById('Status');
        me.progress = document.getElementById('Progress');
        me.percent = document.getElementById('Percent'); 

        me.loaded = 0;
        //每次读取1M
        me.step = 1024 * 1024;
        me.times = 0;
    },
    fileHandler: function(e) {
        var me = h; 

        var file = me.file = this.files[0];
        var reader = me.reader = new FileReader(); 

        //
        me.total = file.size; 

        reader.onloadstart = me.onLoadStart;
        reader.onprogress = me.onProgress;
        reader.onabort = me.onAbort;
        reader.onerror = me.onerror;
        reader.onload = me.onLoad;
        reader.onloadend = me.onLoadEnd;
        //读取第一块
        me.readBlob(file, 0);
    },
    onLoadStart: function() {
        var me = h;
    },
    onProgress: function(e) {
        var me = h; 

        me.loaded += e.loaded;
        //更新进度条
        me.progress.value = (me.loaded / me.total) * 100;
    },
    onAbort: function() {
        var me = h;
    },
    onError: function() {
        var me = h; 

    },
    onLoad: function() {
        var me = h; 

        if(me.loaded < me.total) {
            me.readBlob(me.loaded);
        } else {
            me.loaded = me.total;
        }
    },
    onLoadEnd: function() {
        var me = h; 

    },
    readBlob: function(start) {
        var me = h; 

        var blob,
            file = me.file; 

        me.times += 1; 

        if(file.slice) {
            blob = file.slice(start, start + me.step + 1);
        } else if(file.mozSlice) {
            blob = file.mozSlice(start, start + me.step + 1);
        } 

        me.reader.readAsText(blob);
    },
    abortHandler: function() {
        var me = h; 

        if(me.reader) {
            me.reader.abort();
        }
    }
}; 

h.init();
</script>
</body>
</html>

本文代码以chrome测试为主。

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

(0)

相关推荐

  • JavaScript实现大文件分片上传处理

    很多时候我们在处理文件上传时,如视频文件,小则几十M,大则 1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题: 1.文件过大,超出服务端的请求大小限制: 2.请求时间过长,请求超时: 3.传输中断,必须重新上传导致前功尽弃 这些问题很影响用户的体验感,所以下面介绍一种基于原生JavaScript进行文件分片处理上传的方案,具体实现过程如下: 1.通过dom获取文件对象,并且对文件进行MD5加密(文件内容+文件标题形式),采用SparkMD5进行文件加密: 2.进行分片设置,文件Fil

  • JavaScript 上传文件限制参数案例详解

    项目场景: 1,上传文件限制 功能作用: 1,防止前端操作上传异常文件 2,限制符合的规则,优化展示模型 功能实现: 1,获取file实例 2,执行校验规则方法 代码如下: //大小限制 checkFileSize(file, rules) { return new Promise((resolve, reject) => { file.size / 1024 / 1024 > rules ? reject() : resolve() }).then( () => { return tr

  • JS可断点续传文件上传实现代码解析

    刚开始学习前端开发就碰到文件上传问题,还要求可断点续传.查了很多资料,发现H5的file API刚好可以满足我们的需求,也遇到了一些问题,于是记录下来为有同样需求的朋友提供一些帮助. 一.首先,为了引入文件对象,需要在H5页面上放置一个file类型的输入标签. <input type="file" onchange="fileInfo()"> 当选择文件之后显示文件相关信息: function fileInfo() { let fileObj = doc

  • JavaScript 使用Ckeditor+Ckfinder文件上传案例详解

    目录 一.准备工作 二.解压 三.开始集成 一.准备工作 Ckeditor_4.5.7_full + Ckfinder_java_2.6.0 二.解压 1.解压ckeditor,和平常文件解压相同,正常解压即可 2.解压ckfinder,解压完成后进入ckfinder文件夹下,发现有CKFinderJava-2.6.0.war文件,继续解压. 3.注意看红框部分 三.开始集成 1.准备工作完成,将图1中的ckeditor,及图3中的ckfinder文件夹拷贝到我们自己的项目的WebContent

  • JS+html5实现异步上传图片显示上传文件进度条功能示例

    本文实例讲述了JS+html5实现异步上传图片显示上传文件进度条功能.分享给大家供大家参考,具体如下: <html> <head> </head> <body> <p> emo_album_id:<input type="text" name="emo_album_id" id="emo_album_id" value='1'> </p> <p> na

  • Javascript读取上传文件内容/类型/字节数

    在网站开发的某些情况下我们需要上传文件到服务器,在这个过程中可能会对文件做一定的限制,比如说文件格式,文件大小等,在一些情况下我们上传文件其实是为了获取其中的内容在前端区域展示,这个时候就不需要将文件上传到服务器,完全可以通过Javascript来获取上传文件内容然后进行展示,既加快了操作速度,也减轻了服务器的负载和存储.接下来就是一个实际操作的过程: 首先来看一下一个上传文件对象的属性: UI设计(React+Material-ui) ... const styles = theme => (

  • 原生js实现文件上传、下载、封装等实例方法

    一 .下载 1.代码 const fileDownloadClick = (obj) => { // 解决兼容 if( document.all ){ obj.click(); } else { let event = document.createEvent("MouseEvents"); event.initEvent('click', true, true); obj.dispatchEvent(event); } } const fileDownload = (res,o

  • JS中FileReader类实现文件上传及时预览功能

    FileReader是H5浏览器才支持的JS类,如果不支持H5de浏览器可以使用FormData类实现文件的上传预览,使用可以参考我的下一篇博客:JS中FormData类实现文件上传 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="wid

  • jquery实现异步文件上传ajaxfileupload.js

    本文实例为大家分享了jquery实现异步文件上传的具体代码,供大家参考,具体内容如下 ajaxfileupload.js 异步上传文件: 直接引用. 调用方法: $.ajaxFileUpload({ url:'',//后台接口地址 type: "post", secureuri: false, //一般设置为false fileElementId: 'ofx', // 上传文件的id.name属性名 dataType: 'json', success: function(data, s

  • JS中FormData类实现文件上传

    本文实例为大家分享了JS中FormData类实现文件上传的具体代码,供大家参考,具体内容如下 上篇文章讲到了FormReader类实现文件上传,但是那是HTML5的新特性,在不支持H5的浏览器上则无法使用.这次介绍一个JS的普通类FormData,在不支持H5浏览器环境下也可以文件上传和预览,并且还能监控上传进度. 案例一:xhr.upload.onprogress监控文件的上传进度,并且动态显示 <!DOCTYPE html> <html lang="en">

  • js 实现文件上传样式详情

    目录 1.概述 2.创建对象的参数 3.监听例子 4.使用方法 5.源代码 1.概述 这个js包括按钮样式,列表样式.带有删除.添加.放大(使用的是自带的放大功能,提供有API来放入你的弹窗来进行展示) 可监听的事件 Value wdaasd onlargeClickCallBack 如果想使用自己的弹窗,只需要监听这个函数,拿到返回值给你的弹窗的img->href进行赋值即可 imgFile对象(包括这个被点击图片的全部信息)that(这个js的全局唯一对象,可以在这里面拿到你所有的值) on

随机推荐