精华内容
下载资源
问答
  • h5中blob解析

    万次阅读 2018-02-08 09:58:38
    图片的上传我们用的是FormData,它可以添加Blob类型的对象进去,那Blob类型除了从input[type=file]中直接获取,还能靠什么生成呢?自然是ArrayBuffer!好了,裁剪图片的功能要用到DataURL,上传图片的功能要用到...

     刚开始做前端的时候,有个功能卡住我了,就是裁剪并上传头像。当时两个方案摆在我面前,一个是flash,我不会。另一个是通过iframe上传图片,然后再上传坐标由后端裁剪,而我最终的选择是后者。有人会疑惑,为什么不用H5的Canvas和FormData,第一要考虑ie8的兼容性,第二那时候眼界没到,这种新东西光是听听都怕。

      后来随着Mobile项目越做越多,类似的功能开发得也越来越多,Canvas+FormData成为了标配方案。但做的多了却一直没有静下心来研究,浏览器怎么使用H5的方式裁剪并把文件发送出去,回过头看都是知其然不知其所以然。这篇随笔先做个初步的拆解,就是当通过input选择一张图片后,这张图片在浏览器里是怎样的一个存在。

      文件操作一直是早期浏览器的痛点,全封闭式,不给JS操作的空间,而随着H5一系列新接口的推出,这个壁垒被打破。对,是一系列接口,以下会涉及到如下概念:Blob、File、FileReader、ArrayBuffer、ArrayBufferView、DataURL等,其他如FormData、XMLHttpRequest、Canvas等暂不深入。

      我们先创建一个简单的页面,只有一个input[type=file]。

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
    </head>
    <body>
      <input type="file">
    </body>
    </html>
    复制代码

      然后我们在JS中获取这个元素

    var input = document.querySelector('input[type=file]');

      可以看到这个元素有个属性files,它的类型是FileList。这个类不做过多介绍,就是一个类数组,由浏览器通过用户行为往里面添加或删除元素,JS只有访问其元素的接口,无法对其进行操作。而files的元素就是File类型,File是blob的子类,比blob主要多出一个name的属性。

      现在我们选取一个文件,这里问题来了,这个元素是文件在浏览器的完整备份,还是一个指向文件系统的引用?答案是后者,我们选定文件,然后修改文件名,再上传文件,浏览器报错了。

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
    </head>
    <body>
      <form name='test'>
        <input type="file">
        <input type="submit" value="提交">
      </form>
      <script>
        var input = document.querySelector('input[type=file]'),
            form = document.test;
        form.addEventListener('submit', function(e) {
          e.preventDefault();
          var file = input.files[0],
                fd = new FormData(),
                xhr = new XMLHttpRequest();
          fd.append('file', file);
          xhr.open('post', '/upload');
          xhr.send(fd);
        });
      </script>
    </body>
    </html>
    复制代码

      使用chrome打开chrome://blob-internals/,可以看到一条这样的记录

      可见这仅仅是一条引用。第二个问题来了,如果我们要对图片进行处理,那么只拿到引用是不行的,肯定要在浏览器有一份数据的备份,那么怎么获取这个备份呢?答案就是FileReader,FileReader的对象主要有readAsArrayBuffer、readAsBinaryString、readAsDataURL、readAsText等方法,它们的入参都是Blob对象或是File对象,结果对应最终获取的数据类型。这几个方法是异步的,读取过程中会抛出对应的事件,其中读取完毕的事件为load,所以数据的处理要放在onload下。我先给一个简单的example:

    复制代码
    input.addEventListener('change', function() {
      var file = this.files[0],
          fr = new FileReader(),
          blob;
      fr.onload = function() {
        blob = new Blob([this.result]);
      };
      fr.readAsArrayBuffer(file)
    });
    复制代码

      当用户选取图片时,调用FileReader的readAsArrayBuffer把图片数据读出来,然后生成新的blob对象保存在浏览器中。查看chrome://blob-internals/,可以注意到这一项:

      对应的就是刚才的blob,可以对比length和图片本身的大小。上面那个demo很突兀,完全没有解释什么是ArrayBuffer,为什么创建blob要传入一个ArrayBuffer。那么第三个问题来了,什么是ArrayBuffer、BinaryString、DataURL、Text,它们有什么联系和不同,Blob类到底是个什么东西?首先,图片是个二进制文件,它的内容也是由0和1组成的。用户肯定是看不懂0和1的组合的,能看懂的只有最终展示的图片,而程序员也看不懂0和1,但程序员能看懂另外几种0和1变换后的组合。它们就是以上的4种:ArrayBuffer、BinaryString、DataURL和Text。

      其中ArrayBuffer是最接近二进制数据的表现的,可以理解为它就是二进制数据的存储器,这也是为什么二进制文件的Blob需要传入ArrayBuffer。正因为它的内部是二进制数据,所以我们是不可以直接操作的。这时候就需要一个代理者帮助我们读或写,这个代理者就是ArrayBufferView。

      ArrayBufferView不是一个类,而是一个类的集合,包括:Int8Array、Uint8Array、Uint8ClampedArray、Int16Array、Uint16Array、Int32Array、Uint32Array、Float32Array、Float64Array和DataView,分别表示以8位、16位、32位、64位数字为元素对ArrayBuffer内的二进制数据进行展现,它们都有统一的属性buffer指向对应的ArrayBuffer。栗子暂时不举,之后会用到。

      ArrayBuffer简单介绍了,那什么是BinaryString呢?是二进制数据直接以byte的形式展现的字符串,比如1100001,用Uint8表示就是97,用BinaryString表示就是'a'。对,前者是charCode,后者是char,所以BinaryString和Uint8Array之间是可以自由转换的。

      接下来是DataURL了,这是一个经过base64编码的字符串,它的组成如下:

    data:[mimeType];base64,[base64(binaryString)]

      除了固定的字符串部分,它主要包含两个重要信息即中括号括起的部分,mimeType和base64编码后的binaryString,从它里面我们可以这样取到这两个信息。

    var binaryString = atob(dataUrl.split(',')[1]),
        mimeType = dataUrl.split(',')[0].match(/:(.*?);/)[1];

      最后,Text是什么呢?在ftp上,文本传输和二进制传输的区别是什么,那Text类型和BinaryString类型的区别就是什么了,也就是Text类型是经过一定转换的BinaryString,对于图片来说,这个类型是用不到的。

      好了,现在我们了解了一张图片在浏览器里以数据的形式可以表现为ArrayBuffer、BinaryString、DataURL,那么第四个问题来了,它们各有实际用途呢?我们从应用场景出发,回到文章开头的问题,图片的裁剪和上传。图片的裁剪我们要倚仗牛逼的canvas,而canvas的context有这么一个方法toDataURL,就是把canvas的内容转换为图片数据,而数据的表现形式就是DataURL!图片的上传我们用的是FormData,它可以添加Blob类型的对象进去,那Blob类型除了从input[type=file]中直接获取,还能靠什么生成呢?自然是ArrayBuffer!好了,裁剪图片的功能要用到DataURL,上传图片的功能要用到ArrayBuffer,那怎么从DataURL转换为ArrayBuffer呢?我们知道DataURL很重要的组成部分就是经过base64编码的BinaryString,那么很显然我们可以从DataURL中提取BinaryString,而BinaryString就是ArrayBuffer对应的Uint8Array的字符形式的表现,所以可以由BinaryString生成ArrayBuffer,那么DataURL到ArrayBuffer之间的桥就是BinaryString!

      到现在为止,我们说了很多概念,然而这并没有什么卵用,验证概念的方法不是提出新的概念,而是建立一个example。以下的example就是把图片数据从input中取出,然后以DataURL的格式进行预览,提交时把预览生成图片上传的整个流程。

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
    </head>
    <body>
      <form name='test'>
        <input type="file" name='file'>
        <input type="submit" value="提交">
      </form>
      <img src="" alt="">
      <script>
        var img = document.querySelector('img'),
            preview;
        document.test.file.addEventListener('change', function() {
          var fr = new FileReader();
          fr.onload = function() {
            preview = this.result;
            img.src = preview;
          };
          fr.readAsDataURL(this.files[0]);
        })
        document.test.addEventListener('submit', function(e) {
          e.preventDefault();
          var binaryString = atob(preview.split(',')[1]),
              mimeType = preview.split(',')[0].match(/:(.*?);/)[1],
              length = binaryString.length,
              u8arr = new Uint8Array(length),
              blob,
              fd = new FormData(),
              xhr = new XMLHttpRequest();
          while(length--) {
            u8arr[length] = binaryString.charCodeAt(length);
          }
          blob = new Blob([u8arr.buffer], {type: mimeType});
          fd.append('file', blob);
          xhr.open('post', '/upload');
          xhr.send(fd);
        })
      </script>
    </body>
    </html>
    复制代码

      现在图片已经被我们发射出去了,那么图片在协议包里是以怎样的数据形式存在的呢?当然是以二进制的形式,我们抓一下包,发现在fiddler里面这个二进制串会转换为字符串,即上面的binaryString。

      既然通过发送的blob到最后在数据包里都是以binaryString的形式展示,那么是否可以直接使用xhr.send(binaryString)发送图片呢?貌似是可以的,但我们试一下就会发现问题,服务器获取到的信息不能生成一张图片,说明数据被破坏了。那么数据是谁破坏的呢?这个罪魁祸首就是send,当send的参数是字符串的时候,会对字符串进行utf8编码。我们看下相同的图片通过blob发送出去和通过binaryString直接发送出去的数据会有什么不同。这里我们用wireshark抓包,因为wireshark会自动对数据块进行分割,可以比较直观的看到图片所对应的数据。PS: 这张图片一张1px白色的png。

     

       前面是正常的图片数据,后面是经过了utf8编码的图片数据。我们可以看到数据确实被破坏了,当然在知道元数据是binaryString的情况下,这种破坏是可以恢复的,不过不是这里讨论的范畴了,感兴趣的可以跳转阮老师的博客《字符编码笔记:ASCII,Unicode和UTF-8》

      好了,整个图片在浏览器端的拆解到此结束。理解了这些,就走完了写出牛逼的客户端图片裁剪工具的第一步。

    展开全文
  • 需求:表格转换,上传一个表格,解析后台返回的文件流,下载转换后的表格 html: <div class="edit_dialog"> <el-dialog title="表格转换" :visible.sync="execlChangeVisible" width="600px" :append...

    需求:表格转换,上传一个表格,解析后台返回的文件流,下载转换后的表格

    html:

     <div class="edit_dialog">
          <el-dialog title="表格转换" :visible.sync="execlChangeVisible" width="600px" :append-to-body="true" :close-on-click-modal="false">
            <!--表单开始-->
            <el-form label-width="85px">
              <el-form-item label="excle表格:">
                <el-upload
                  class="upload-demo"
                  ref="uploadChangeFile"
                  action="string"
                  :http-request="onChangeRequest"
                  accept=".xlsx, .xls"
                  :limit="1"
                  :auto-upload="false"
                >
                  <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
                </el-upload>
              </el-form-item>
            </el-form>
            <!--表单结束-->
            <span slot="footer" class="dialog-footer">
              <el-button type="primary" @click="submitChangeFile" :disabled="zipDisabled">确 定</el-button>
            </span>
          </el-dialog>
        </div>

    js部分

      //表格转换上传
        submitChangeFile () {
          this.$refs.uploadChangeFile.submit();
        },
      //自定义上传方法(xxxRequest),表格转换上传
        onChangeRequest (data) {
          const loading = openLoad(this, "Loading...");
          let formData = new FormData();
          formData.append('file', data.file)
          this.$ajax.post(this.$store.state.localIP + "goods/excelOriginalGoods", formData, {
            headers: {
              'Content-Type': 'multipart/form-data',
            },
            responseType: 'arraybuffer'
          })
            .then(response => {
              loading.close();
              if (response.status == 200) {
                this.execlChangeVisible = false;
                //转化成功后,对返回的链接进行下载处理
                const tempBlob = new Blob([response.data], { type: 'application/ json' })
                // 通过 FileReader 读取这个 blob
                const reader = new FileReader()
                reader.onload = e => {
                  const res = e.target.result
                  // 此处对fileReader读出的结果进行JSON解析
                  // 可能会出现错误,需要进行捕获
                  try {
                    const json = JSON.parse(res)
                    if (json) {
                      // 解析成功说明后端导出出错,弹出错误信息,并返回
                      this.$message.error(json.retMsg);
                      return
                    }
                  } catch (err) {
                    // 该异常为无法将字符串转为json,说明返回的数据是一个流文件
                    // 不需要处理该异常,只需要捕获即刻
                  }
                  // 如果代码能够执行到这里,说明后端给的是一个流文件,再执行上面导出的代码
                  if (navigator.userAgent.indexOf("Chrome") != -1) {
                    // type 为需要导出的文件类型
                    const blob = new Blob([response.data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" })
                    // 兼容不同浏览器的URL对象
                    const url = window.URL || window.webkitURL || window.moxURL
                    // 创建下载链接
                    const downloadHref = url.createObjectURL(blob)
                    // 创建a标签并为其添加属性
                    let downloadLink = document.createElement('a')
                    downloadLink.href = downloadHref
                    console.log(downloadHref)
                    downloadLink.download = '转化后的表格.xlsx'
                    // 触发点击事件执行下载
                    downloadLink.click()
                    window.URL.revokeObjectURL(downloadHref);  //下载完成进行释放
                  } else {
                    //兼容ie
                    window.navigator.msSaveOrOpenBlob(blob, '转化后的表格.xlsx')
                  }
                }
                // 将blob对象以文本的方式读出,读出完成后将会执行 onload 方法
                reader.readAsText(tempBlob)
              } else {
                this.$message.error(response.data.retMsg);
              }
            })
            .catch((error) => {
              loading.close();
              console.log(error)
              this.$message.error('转化失败!');
            })
        },

     

    展开全文
  • grunt-copy-gitignore-blob 使用gitignore-blob解析.gitignore文件并获得一种文件模式,该模式会否定所有提到的文件/文件夹 如何运行项目 npm install grunt
  • 解析blob视频

    千次阅读 2020-07-31 10:49:11
    解析blob视频 可以看到视频地址使用blob隐藏掉真实地址 打开network,看到如下信息,那就相当好办了,可以看到视频被分开成ts,那么只要只要整合起来就好 打开index.m3u8,内容如下 接下来就是读取了,java代码如下...

    解析blob视频


    可以看到视频地址使用blob:https://开头隐藏掉真实地址
    在这里插入图片描述
    打开network,看到如下信息,那就相当好办了,可以看到视频被分开成ts,那么只要只要整合起来就好
    在这里插入图片描述
    打开index.m3u8,内容如下
    在这里插入图片描述
    接下来就是读取了,java代码如下,这里只做测试,没用多线程,逐个下载很慢

    public class Test4 {
        private String baseUrl="";//网站url
        public static void main(String[] args) throws Exception {
            File file=new File("D:\\123.txt");
            BufferedReader isr=new BufferedReader(new  InputStreamReader(new FileInputStream(file)));
            String s=null;
            FileOutputStream fos=new FileOutputStream("D:\\12.mp4",true);
            while ((s=isr.readLine()) !=null){
                if(s.startsWith("4494a")){
                    System.out.println(s);
                    getResource(s,fos);
                }
            }
            isr.close();
            fos.close();
        }
        public static void getResource(String str,FileOutputStream fos) throws Exception {
            URL url=new URL(baseUrl+str);
            HttpURLConnection connection= (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            InputStream is=connection.getInputStream();
            int i=0;
            byte[] b=new byte[1024];
            while ((i=is.read(b))!=-1){
                fos.write(b,0,i);
            }
            is.close();
        }
    }
    

    效果,可以看到能够正常播放
    在这里插入图片描述

    展开全文
  • 解析下载blob视频

    万次阅读 2019-10-01 16:43:44
    blob后面的网址不能直接访问。 比如百度百科搜索中的视频:离子液体 这篇博客教你如何下载此类视频。 环境 360浏览器 没有安装360浏览器的就麻烦安装一下吧^_^ 安装插件Flash Video Download...

    前言

    浏览器中有些视频是通过blob:https://baike.baidu.com/bf834217-9442-4c98-9ef6-0bd5f3408a4e的形式给出的。blob后面的网址不能直接访问。
    比如百度百科搜索中的视频:离子液体

    这篇博客教你如何下载此类视频。

    环境

    • 360浏览器

    没有安装360浏览器的就麻烦安装一下吧^_^

    安装插件Flash Video Downloader

    点击右上角的扩展中心

    搜索Flash Video Downloader
    点击安装

    下载视频

    播放视频,点击插件,根据需要选择下载。


    展开全文
  • let result = ''; let reader = new FileReader();... //FileReader:从Blob对象中读取数据 reader.onload = function() { result = JSON.parse(pako.inflate(reader.result,{to:'string'})); //.
  • js 解析blob数据

    千次阅读 2021-03-17 14:29:42
    背景:前端通过websocket和其他设备通信,js中获取到的数据是Blob 在websocket中获取到Blob对象的数据以后 //websocket接收到数据 websocket.onmessage = function (event){ //判断是否为Blob格式的数据 if ...
  • springboot 读取Blob 解析成文件

    千次阅读 2018-08-27 16:57:33
    /** * 根据应聘者id下载对应的pdf简介 * @param request * @param response * @param id * @return * @throws IOException */ @SuppressWarnings("unused"... @RequestMapping(value = "...
  • oracle blob 字段的解析

    2017-02-06 10:48:58
    oracle.sql.BLOB data = (oracle.sql.BLOB)resultSet.getBlob("data"); InputStream is = data.getBinaryStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); ...
  • java读取并解析oracle中blob类型XML数据

    千次阅读 2018-07-06 15:59:27
    //必须加去除空格操作,否则无法解析。  System.out.println(newStr);  String result="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Ciqresult><CusCiqNo>bbb</CusCiqNo><EntDealNo>...
  • JavaScript Blob 对象详解

    2020-07-19 22:23:07
    在一般的 Web 开发中,很少会用到 Blob,但 Blob 可以满足一些场景下的特殊需求。Blob,Binary Large Object 的缩写,代表二进制类型的对象。Blob 的概念在一些数据库中有使用到,例如,MYSQL中的 BLOB 类型就表示二...
  • Blob分析

    2020-03-02 14:12:26
    Blob翻译成中文,是“一滴”,“一抹”,“一团”,“弄脏”,“弄错”的意思。在计算机视觉中的Blob是指图像中的具有相似颜色、纹理等特征所组成的一块连通区域。显然,Blob分析其实就是将图像进行二值化,分割得到...
  • BLOB类型转换成字符串类型

    千次阅读 2019-10-29 11:31:18
    BLOB类型转换成字符串类型blob_to_varchar2 一开始遇到这个问题的时候我走错了方向,一直没有解决,后来再网上找到了一个函数,亲测有效。 blob_to_varchar2 Create Or Replace Function Blob_To_Varchar (Blob_In ...
  • sqlite3数据库之blob数据类型读写 近期在开发过程中需要在数据库中保存二进制文件,于是去了解了一下sqlite3的数据类型,发现blob可以存储二进制数据。 但是blob要如何操作呢?用什么语句呢? 其实它是需要操作...
  • Java对blob文件的保存和解析

    万次阅读 2014-07-11 22:46:24
    1)在Java中经常需要保存一个xml文件到数据中,这个时候blob是最好的选择。但是保存的时候发现可不是那么容易的。网上很多资料都是先保存一个空的数据,再一点点插入进去。 InputStream in = new FileInputStream...
  • 一文读懂Blob

    2020-09-22 11:12:14
    提起Blob大部分前端同学可能比较生疏,Blob全称binary large object即二进制大对象,顾名思义Blob用于存储二进制数据。在前端领域中Blob赋予了我们直接操作二进制数据的能力,Blob不一定是JavaScript原生格式的数据...
  • java读取大字段blob类型

    热门讨论 2010-05-16 15:33:09
    java读取大字段,介绍java如何读取大字段blob,解决程序员头疼问题
  • python读取BLOB格式数据

    2020-10-10 17:12:14
    !... 如图,数据库里存的该格式 ``` ...if __name__ == '__main__': ... sql = 'select data from test where id = x' ...数据是用gzip压缩的,但是读出来不是byte格式数据、、、、求助,是不是读取方法不对
  • 主要介绍了深入解析HTML5中的Blob对象的使用,是HTML5入门学习中的基础知识,需要的朋友可以参考下
  • JS-前端使用Blob和File读取文件

    万次阅读 2019-04-07 15:10:16
    Blob及其属性和方法 File FileReader及其属性和方法 URL及其属性和方法 历史上,JavaScript 无法处理二进制数据。如果一定要处理的话,只能使用 charCodeAt() 方法,一个个字节地从文字编码转成二进制数据,还有一...
  • if (response.request.responseType === 'blob') { const reader = new FileReader() reader.readAsText(response.data, 'utf-8') reader.onload = function() { response.data = JSON.parse(reader.result as ...
  • Blob 接收 Excel 损坏

    2020-09-23 14:18:05
    参考:https://blog.csdn.net/mollerlala/article/details/103178244?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-1-103178244.nonecase&utm_term=blob%E5%AF%BC%...
  • 封装axios时, responseType: ‘blob’,将影响第一种情况读取reponse为blob,不能直接读取code和msg,此时就需要将blob的内容转成文件读取,不能取消responseType: ‘blob’,取消会影响正常下载 调接口,根据...
  • blob类型对象转为file类型对象

    万次阅读 多人点赞 2019-08-01 19:38:42
    今天楼主遇到一个问题,显示js解压缩文件,然后将解压出来的文件上传到服务器,接口要求传file类型 但是通过jszip解压出来,然后再async之后只能是以下几种类型 ... Blob,没人写怎么用Blob => Fi...
  • python查询oracle数据blob类型字段 在网上找了代码,内容很简单,直接上代码 import os import cx_Oracle # os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8' db_orcl = cx_Oracle.connect("用户/sid@...
  • The <code>tile_data</code> field is a <code>BLOB</code> and i'm trying to query the database and get the corresponding images (stored as blob types). <p>So far the queries are OK but i'm getting ...
  • BLOB字段转化成字符串String

    万次阅读 2018-10-25 09:39:35
    <result column="MONENT" property="monent" jdbcType="BLOB" /> <result column="RESULE" property="resule" jdbcType="BLOB" /> Controller @RequestMapping(value = "/InterfaceLoginfo", method = ...
  • axios配置responseType: 'blob'时,接口返回成功的数据是正常的文件流,返回失败的时候也会以文件流的形式下载到本地,但是是一个损坏的文件。 通过观察发现:有效的情况下返回的type是application/octet-stream...
  • } public static void mothod2(File f,Blob blob_photo) throws IOException { byte[] obj = (byte[])blob2Object(blob_photo); FileImageOutputStream out = null; out = new FileImageOutputStream(f); out.write...
  • 根据BLOB生成附件

    2017-06-12 10:34:30
    根据BLOB生成一个附件,首先判断该附件是否已经存在,如果不存在继续生成附件 public isexists(){ String tempFilePath="附件路径"; byte[] fileStream = "附件数据流"; File tempFile = new File...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,101
精华内容 18,840
关键字:

blob解析