前端本地文件操作与上传 视频/图片/音频

#前端本地文件操作与上传

前端无法像原生一样操作文件,否则打开网页就能把用户的东西偷光,所以只能通过以下三种方式触发:

  1. 通过input的file选择本地文件
  2. 通过拖拽方式把文件拖过来
  3. 在编辑框里面复制粘贴
<body>
    <form action="" id="file-up">
        <input type="file" name="file">

    </form>
    
</body>
<script>
    var form = document.forms.namedItem("file-up")
    form["file"].onchange = function(){
        console.log(`file name is ${this.value}`)   ///这里的路径是一个假的路径,也就是说浏览器无法获取文件真实存放的位置。
        // console.log(this.form)
        let formData = new FormData(this.form)
        formData.append("fileName",this.value)
        console.log(formData)           ///这里的formData是个空的,无法查看、修改、删除里面的内容,只能append字段
    }
</script>

formData无法得到文件的内容,而使用fileReader可以读取文件的内容。

form["file"].onchange = function(){
    console.log(`file name is ${this.value}`)
    // console.log(this.form)
    let fileReader = new FileReader()
    fileType = this.files[0].type;
    fileReader.onload = function(){
        if(/^image\/[jpg/jpeg/png/gif]/.test(fileType)){   ///web不是所有的图片都是可以用img标签展示出来通常是jpg/png/gif
            // 读取结果在fileReader.result里面
            let img = new Image()
            img.src = this.result;
            console.log(this.result)   ///读取的结果base64数据
            document.body.appendChild(img)
        }
    }
    console.log(this.files[0])  //打印file对象  里面包含里文件大小、文件名、文件类型(这里判断文件类型会比判断文件名更准确)
    let fileData = fileReader.readAsDataURL(this.files[0])
}

fileReader的读取方式

readAsArrayBuffer(file)	  二进制读取(读取结果直接转成整数数组)
readAsBinaryString(file)	二进制字符串方式读取,结果是二进制内容的utf-8(已经被废弃)
readAsDataURL(file)	  以base64形式读取(任何文件都能转成base64)
readAsText(file,encoding)	按字符读取文件内容,结果用字符串形式表示
abort()	终止文件读取操作



事件
onabort	当读取操作被中止时调用
onerror	当读取操作发生错误时调用
onload	当读取操作成功完成时调用
onloadend	当读取操作完成时调用,无论成功或失败
onloadstart	当读取操作开始时调用
onprogress	在读取数据过程中周期性调用

##拖拽方式的判断

form["file"].ondrop = function(event){
    console.log(event)
    event.preventDefault();
    event.cancelBubble = true;  ///一定要防止冒泡
    let file = event.dataTransfer.files[0];
    readImage(file)
}
function readImage(file){  // 只能读取blob数据
    let fileReader = new FileReader(file)
    fileReader.readAsDataURL(file)
    fileReader.onload = function(){
        // console.log(file.type)
        if(/^image\/[jpeg|png|gif]/.test(file.type)){
            // 读取结果在fileReader.result里面
            let img = new Image()
            img.src = this.result;
            // console.log(this.result)  ///base64的结果
            document.body.appendChild(img)
        }
    }
}
//或者可以添加到formData
let formData = new FormData();
formData.append("fileName",file)

##粘贴的方式

通常在一个编辑框里操作,如把一个div的contenteditable设置为true ,代码如下:

var edit = document.getElementById("edit")


edit.onpaste = function(event){
    console.log(event)
    let file = event.clipboardData.files[0]
    readImage(file)
    //也可以通过另一种方式获取这个文件
     var item = e.clipboardData.items[i];
     var blob = item.getAsFile();
}

但是safari的粘贴不是通过event传递的,而是直接在输入框添加了一张照片,新建了一个img的标签,将img的src指向一个blob的本地数据

blob 是一种文件的存储格式(blob派生了file),它可以存储几乎任何格式的内容

///blob
var data = {hello:'blob'}
var blob = new Blob([JSON.stringify(data)],{type:'application/json'})
console.log(blob)   ///Blob(16) {size: 16, type: "application/json"}

##base64 转 blob

///base64 => blob
    function b642blob(b64,contentType,sliceSize){ 
        contentType = contentType || '';
        sliceSize = sliceSize || 512;

        let byteCharacters = window.atob(b64);  /// 把base64还原   btoa 是把内容转化为base64
        let byteArrays = [];
        for(let offset = 0; offset<byteCharacters.length ; offset++){
            let slice = byteCharacters.slice(offset , offset + sliceSize);

            let byteNumbers = new Array(slice.length);

            for(let i = 0; i< slice.length; i++){
                byteNumbers[i] = slice.charCodeAt(i);
            }
            let byteArray = new Uint8Array(byteNumbers);

            byteArrays.push(byteArray)
        }

        var blob = new Blob(byteArrays,{type:contentType})
        console.log(blob)
        return blob;
    }

##XMLHttpRequest 2.0 可以获取文件的上传进度

xhr.upload.onprogress = function(event){
    if(event.lengthComputable){
        // 当前上传的百分比
        duringCallback((event.loaded/event.total)*100)
    }
}

上传blob

//上传数据
        $.ajax({
            url: url,
            type: 'post',
            processData: false,
            contentType: false,
            data: formData,
            dataType: 'json',
            success: function (data) {
                var obj = eval(data);
                if (obj.responseCode == '0') {

                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                alert(textStatus + "---" + errorThrown);
            }
        });

input 调用相机/录视频

// 相机
<input type="file" accept="image/*" capture="camera">

// 视频
<input type="file" accept="video/*" capture="camcorder">

// 音频
<input type="file" accept="audio/*" capture="microphone">

capture表示,可以捕获到系统默认的设备,比如:camera--照相机;camcorder--摄像机;microphone--录音。

accept表示,直接打开系统文件目录。

input:file标签还支持一个multiple属性,表示可以支持多选
相关推荐
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:白松林 返回首页