zoukankan      html  css  js  c++  java
  • js 读取本地文件(必须通过input控件才能实现) 及 下载文件

    js 操作 文件的实现原理:

    1、js是不能直接操作(读写)文件的,html的  input[type="file"] 控件是可以读取文件数据(获取文件数据流)的。js可以获取这个 input 标签的数据流,这样js就 可以操作 这个文件的数据流了,获取这个文件中数据了( js 还是不能 将数据写入文件中)。

       input[type="file"] 控件 操作文件,只能是用户主动 加载 文件到浏览器上。浏览器这种机制,确保了js无法 操作文件。只能在用户主动允许的情况下,将文件的数据流给 input控件。

    2、input type="file"  控件文档:https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Input/file

    3、js 获取 input中的文件流对象,里面只有几个属性(参考上面链接)。这个文件流数据是看不到,对这个文件流数据的操作,需要用对应的API接口,如下:

    <input type="file" id="file"/>
        var input = document.querySelector('input');
        input.addEventListener('change', function() {
            console.log(this.files); // 我们是无法直接在 this.files 对象中获取到 数据流的,需要使用 FileReader 对象去 读取的。
        }, false);

      处理 不同格式的数据流,需要使用  对应读取数据流的 API(如,文本文件,使用readAsText去读取,获取对应的文本数据;图片文件,使用readAsDataURL去读取,获取对应文件的base64的数据格式)。

      a、读取 文本文件

        var input = document.querySelector('input');
        input.addEventListener('change', function() {
          if(this.files.length){
            let file = this.files[0];
            let reader = new FileReader();
            reader.onload = function(){
              console.log(this.result);  // 文件数据流,变成相应格式数据了。( 文本文件,就输出文本内的文本数据 )
            };
            reader.readAsText(file);
          }
        }, false);

      b、读取 图片文件

        var input = document.querySelector('input');
        input.addEventListener('change', function() {
          if(this.files.length){
            let file = this.files[0];
            let reader = new FileReader();
            reader.onload = function(){
              console.log(this.result);
            document.getElementById('preview').src = this.result;  // this.result 输入 图片的base64格式的数据
            };
            reader.readAsDataURL(file);
          }
        }, false);

    4、FileReader 属性和方法:https://www.jianshu.com/p/cde728c4e334 

    5、彻底弄懂文件和二进制数据的操作:https://blog.csdn.net/weixin_33807284/article/details/91420517

      a、Blob 对象:Blob对象代表了一段  二进制数据 。(通过这个对象,可以生成一个存在内存中的文本文件,通过a标签下载可以这个文件。如果要生成图片等非文本的文件,比较复杂,一般也不会这么用)

      b、FileList对象:<input type='file' multiple />标签 选择文件后的对象,这个对象指向 本地选中的文件。js是无法获取指向这个文件的url地址的(浏览器的安全机制)。

      c、URL对象:URL对象用于生成指向File对象或Blob对象的URL。(把内存中二进制数据,看成储存在内存中的一个文件。URL对象就是这个文件的路径)

      d、FileReader对象:FileReader API用于读取文件,即把文件内容读入内存。它的参数是File对象或Blob对象。(readAsText  返回文本字符串默认文本编码格式是’UTF-8’,可以通过可选的格式参数)

      个人总结:Blob 对象 和 FileList对象 都是二进制数据源。Blob 对象本身就是一个二进制数据;而FileList对象是指向一个二进制文件,可以获取到这个文件的二进制数据。

             而 URL对象 和 FileReader对象 都是操作这两个 二进制数据源的 API。(FileList对象和Blob对象一样使用,因为FileList对象会隐式转化为 Blob对象)

        <input type="file" id="file"/>
         // URL 对象 对Blob 和 FileList 二进制数据源 操作
            let blob = new Blob(["Hello World"],{ "type" : "text/xml" }); // 本身就是二进制数据
            let input = document.querySelector('input');  // 选择文件后,才有 FileList 对象。所以对input选中文件的操作,应该是input控件 change事件后。
    
            console.log(URL.createObjectURL(blob));   //  blob:null/16e3804c-452f-408b-b514-bbe27a874837
    
            input.addEventListener('change', function() {
                if(this.files.length){
                    let file = this.files[0];
                    console.log(URL.createObjectURL(file)); //  blob:null/88cca1d4-442c-4ac9-a7fd-402b75990d50
                }
            }, false);
        // FileReader 对象对Blob 和 FileList 二进制数据源 操作
            let readerBlob = new FileReader();
            readerBlob.onload = function(){
                console.log(this.result);  // Hello World
            };
            readerBlob.readAsText(blob);
    
            input.addEventListener('change', function() {
                if(this.files.length){
                    let file = this.files[0];
                    let reader = new FileReader();
                    reader.onload = function(){
                    console.log('dd',this.result); // happy new 【这个是文本文件中的文字
                    };
                    reader.readAsText(file);
                }
            }, false);    

    6、

    个人理解:input[type="file"] 控件,选中文件后,这个控件对象就指向这个本地文件,在需要使用这个文件时,通过相应的 API(如,FileReader 对象) 把这个对象指向的文件,读取到内存中(以二进制数据存在)。


     js 操作文件 实践

    一、 ajax传递文件

    1、H5 FormData对象的使用——进行Ajax请求并上传文件   :    https://www.cnblogs.com/lyr1213/p/6238026.html

    2、js发送post请求下载文件:ajax是不能直接下载文件的,所以使用js进行post请求需要借助标签实现。  http://www.cnblogs.com/xiexingen/p/4560547.html 或 https://www.cnblogs.com/micro-chen/p/5367550.html 或 https://www.jianshu.com/p/6a9947cc3849(推荐)

    二、 js通过CSV导入excel数据:https://segmentfault.com/a/1190000015080835?utm_source=tag-newest

       说明:不同格式的文件,他们的本质都是二进制数据。不同 格式的文件,只是数据格式不同,针对不同的文件,使用相应的解码格式就可以获取需要的数据。

    三、用户选中本地的图片,并显示这个图片。 https://segmentfault.com/a/1190000018314505


     前端下载excel文件功能的三种方法https://www.cnblogs.com/houxiaohang/p/6846467.html

    前端下载文件:

    一、请求的文件url,不需要 给请求头或请求体添加信息,设置认证信息(如,请求头 添加 token值)。这种下载链接直接在浏览器地址上输入地址就可以下载,或打开。

      这种请求,有 3种方式下载:

      1、a 标签下载,正规下载方式。a标签上可以设置下载的文件 文件名。(一般都是这种方式下载文件)

      2、location.href = downloadUrl 。这种方式下载只能是浏览器不能识别的文件。不然无法下载,而且下载的文件不能命名。

      3、window.open(downloadUrl) 。 这种方式和 第二种 是一样的,只是这种方式是打开一个新的窗口跳转到下载链接,而第二种是在当前窗口跳转到下载链接。

    这种请求 通过 a标签,设置down属性 就可以下载。  

    二、请求的文件url,需要权限控制(不管是get还是post请求都一样),这种文件的下载只能通过js的ajax请求实现。直接在浏览器上输入文件请求地址,下载不了。(后管平台中展示的数据 常常需要导出excel文件,就是这种请求)

      参考:https://www.cnblogs.com/roseAT/p/11074765.html  或  https://blog.csdn.net/aydongzhiping/article/details/82462473

      1、因为 请求有权限,需要在请求上添加认证信息(如,请求头上添加token值),只有ajax请求可以给请求头添加信息。

      2、ajax请求文件,请求回来的数据是一个二进制数据。这个请求很简单,难点是把二进制数据下载下来。这里关键是用到了 window.URL 这个API。

      3、URL对象用于生成指向File对象或Blob对象的URL。通过这个API可以生成一个指向  内存中二进制数据(ajax请求回来的数据 )的url地址。这时,内存中的二进制数据就可以 和 普通文件那样下载了。

    const requestFile = url => {
      const xhr = new XMLHttpRequest();
      // GET请求,请求路径url,async(是否异步)
      xhr.open('GET', url, true);
      // 设置请求头参数的方式,如果没有可忽略此行代码
      xhr.setRequestHeader(AUTHORIZATION_REQUEST_HEADER, 'Token值');
      // 设置响应类型为 blob
      xhr.responseType = 'blob';
      // 关键部分
      xhr.onload = function (e) {
        // 如果请求执行成功
        if (this.status === 200) {
          const name = xhr.getResponseHeader('Content-disposition');
          const filename = name.substring(20, name.length);
          const a = document.createElement('a');
          // 创键临时url对象
          const downloadUrl = URL.createObjectURL(this.response);
    
          a.href = downloadUrl;  // 这里也可以使用location.href 或 window.open()进行下载,但是这两个不能给文件命名。
          a.download = decodeURI(filename);
          a.click();
          // 释放之前创建的URL对象
          window.URL.revokeObjectURL(downloadUrl);
        }
      };
      // 发送请求
      xhr.send();
    }

      注意:数据的 响应类型很重要,不然返回的数据,xhr对象无法正确处理返回的数据。默认的响应类型 text 类型 ,下载时,响应类型 必须设置 为 blob

           【亲测,用axios插件】没有设置 这个 responseType 的响应类型,xhr 处理后给出的 是字符串数据;设置 响应类型 为 blob,xhr 处理后给出的 是 blob 对象的数据。

    总结:不同的DOM有不同的默认事件行为,一般是在点击事件时触发(如,a标签的下载行为,input-file控件打开文件系统)。js是没有这种行为的,js要实现这种行为就必须借助相应的标签。通过js触发这个标签的事件,执行相应的默认行为。

  • 相关阅读:
    js 判断window操作系统 2种方法
    HTML5 16进制颜色
    html5 动画运动 属性
    html5 动画运动 属性
    html5 图片旋转 --位置定位
    html 5 过渡 属性 高度 宽度 颜色 样式等。。。
    jquery 文档操作
    html5 表单 自带验证
    PHP微信授权登录信息
    接口测试-requests高级用法
  • 原文地址:https://www.cnblogs.com/wfblog/p/9144533.html
Copyright © 2011-2022 走看看