Blob File

news2024/11/18 7:39:35

文章目录

    • 学习链接
    • Blob
      • 创建
        • 演示
      • 分片
        • 演示
    • File
      • input
      • 手动拖拽
      • fetch 从后端获取流
        • 前端代码
        • 后端代码
      • window.showOpenFilePicker
    • Filereader
      • 示例1
      • 示例2
    • ArrayBuffer
      • 创建buffer
      • TypedArray读写buffer
      • DataView读写buffer
      • 与Blob对比
    • Blob Url & DataUrl
      • 示例1
      • 示例2

学习链接

Blog & File B站视频
今天一次性给你讲清楚:File、Blob、FileReader、ArrayBuffer、Base64
web前端文件上传可选择的4种方式

Blob

在这里插入图片描述

Blob 全称为 binary large object ,即二进制大对象。blob对象本质上是js中的一个对象,里面可以储存大量的二进制编码格式的数据。Blob 对象一个不可修改,从Blob中读取内容的唯一方法是使用 FileReader

创建

new Blob(array,options)

  • 其有两个参数:

    • array:由 ArrayBuffer、ArrayBufferView、Blob、DOMString 等对象构成的,将会被放进 Blob;

    • options:它可能会指定如下两个属性

      • type:默认值为 “”,表示将会被放入到 blob 中的数组内容的 MIME 类型。

      • endings:默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入,不常用。

      在这里插入图片描述

演示

在这里插入图片描述
这个 blob 对象上有两个属性:

  • size:Blob对象中所包含数据的大小(字节);
  • type:字符串,认为该Blob对象所包含的 MIME 类型。如果类型未知,则为空字符串。

分片

Blob 对象内置了 slice() 方法用来将 blob 对象分片(注意:Blob对象是不可直接修改的,所以分片返回的是一个新的Blob对象

  • 其有三个参数:

    • start:设置切片的起点,即切片开始位置。默认值为 0,这意味着切片应该从第一个字节开始;

    • end:设置切片的结束点,会对该位置之前的数据进行切片。默认值为blob.size;

    • contentType:设置新 blob 的 MIME 类型。如果省略 type,则默认为 blob 的原始值。

演示

在这里插入图片描述

File

File 接口基于 Blob,继承了 blob 的功能并将其扩展以支持用户系统上的文件。File 对象是特殊类型的 Blob,比Blob要多一些文件相关的属性。

File() 构造器创建新的 File 对象实例:var myFile = new File(bits, name[, options]);

  • bits:一个包含ArrayBuffer,ArrayBufferView,Blob,或者 DOMString 对象的 Array — 或者任何这些对象的组合(所以可以这样创建File,new File([blob],‘test.zip’))。
  • name:表示文件名称,或者文件路径。
  • options: 可选,选项对象,包含文件的可选属性。可用的选项如下:
    • type: DOMString,表示将要放到文件中的内容的 MIME 类型。默认值为 “” 。
    • lastModified: 数值,表示文件最后修改时间的 Unix 时间戳(毫秒)。默认值为 Date.now()。

在 JavaScript 中,主要有两种方法来获取 File 对象:

  • <input> 元素上选择文件后返回的 FileList 对象;

  • 文件拖放操作生成的 DataTransfer 对象;

  • window.showOpenFilePicker

  • fetch 从后端获取

input

  • 但是,注意一下,每次change的时候,需要把这个input的value置为空,接着,仍然选择同一个文件时,也会触发这个change事件
  • 可以添加hidden属性,让这个input标签隐藏掉。或者,写css样式让它隐藏。然后,手动用js调用这个input的click事件。
    在这里插入图片描述

手动拖拽

在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            width: 300px;
            height: 300px;
            border: 1px solid red;
        }
    </style>
    <script>
        window.onload = () => {
            let box = document.querySelector('.box')
            box.ondragover = (e) => {
                e.preventDefault();
            }
            box.ondrop = (e) => {
                e.preventDefault();
                let files = e.dataTransfer.files
                console.log(files);
            }
        }
    </script>
</head>
<body>
    <div class="box"></div>
</body>
</html>

fetch 从后端获取流

从这里,我们可以看到都可以从后端拿到Blob对象了,那就可以操作这个Blob了,前端就可以创建个a标签,添加上download属性,然后用js模拟点击这个a标签,然后把这个a标签移除掉。

在这里插入图片描述

前端代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            width: 300px;
            height: 300px;
            border: 1px solid red;
        }
    </style>
    <script>
        window.onload = () => {
            let btn = document.querySelector('#btn')
            btn.onclick = () => {
                fetch('http://127.0.0.1:8083/file/downloadFile?filename=avatar3.png')
                    .then(response => {
                        console.log(response);
                        return response.blob()// 注意,只能读取一次
                    }).then(result=>{
                        console.log(result);
                    })
            }

            btn2.onclick = () => {
                fetch('http://127.0.0.1:8083/test.json')
                    .then(response => {
                        console.log(response);
                        return response.json() // 注意,只能读取一次
                    }).then(result=>{
                        console.log(result);
                    })
            }
        }


    </script>
</head>

<body>
    <button id="btn">获取avatar3.png</button>
    <button id="btn2">获取test.json</button>
</body>

</html>

后端代码

@GetMapping("downloadFile")
public void downloadFile(@RequestParam("filename") String filename) throws Exception {

    // 告知浏览器这是一个字节流,浏览器处理字节流的默认方式就是下载
    // 意思是未知的应用程序文件,浏览器一般不会自动执行或询问执行。浏览器会像对待,
    // 设置了HTTP头Content-Disposition值为attachment的文件一样来对待这类文件,即浏览器会触发下载行为
    response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
    // ,该响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者网页的一部分),还是以附件的形式下载并保存到本地。
    response.setHeader(HttpHeaders.CONTENT_DISPOSITION,"attachment;fileName="+ URLEncoder.encode(filename, "UTF-8"));
    File file = new File("d:/Projects/practice/test-springboot/src/main/resources/file/" + filename);

    ServletOutputStream ros = response.getOutputStream();

    FileInputStream fis = new FileInputStream(file);
    byte[] bytes = new byte[2 * 1024];
    int len = 0;
    while ((len = fis.read(bytes)) != -1) {
        ros.write(bytes, 0, len);
    }

    ros.flush();
    ros.close();

}

@GetMapping("test.json")
public Object test2() {
    HashMap<String, Object> data = new HashMap<>();
    data.put("halo", "world");
    return data;
}

window.showOpenFilePicker

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script>
        window.onload = () => {
            document.getElementById('openImageFile').addEventListener('click', async () => {
                const handle = await showOpenFilePicker({
                    multiple: true,
                    types: [{
                        description: '图片',
                        accept: { 'image/png': ['.jpg', '.png'] }
                    }]
                })

                if (handle && handle.length) {
                    const handleFile = handle[0]
                    const file = await handleFile.getFile()
                    console.log(file);
                }
            }, false)


        }


    </script>
</head>

<body>
    <button id="openImageFile">打开图片</button>
</body>

</html>

Filereader

通过上面我都知道了blob是不可修改也是无法读取里面的内容的。无法读取里面的内容肯定是不可行的。所以Filereader就提供了读取blob里面内容的方法

FileReader对象提供了以下方法来加载文件:

  • readAsArrayBuffer()∶读取指定Blob中的内容,完成之后,result属性中保存的将是被读取文件的ArrayBuffer数据对象;
  • readAsBinaryString()∶读取指定Blob中的内容,完成之后,result属性中将包含所读取文件的原始二进制数据;
  • readAsDataURL()︰读取指定Blob 中的内容,完成之后,result属性中将包含一个data: URL格式的 Base64字符串以表示所读取文件的内容。
  • readAsText()︰读取指定Blob 中的内容,完成之后,result属性中将包含一个字符串以表示所读取的文件内容。

在这里插入图片描述

示例1

将文件读取为base64 的字符串

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script>
        window.onload = () => {
            
            let iptFile = document.querySelector('#iptFile')

            iptFile.onchange = (e) => {
                console.log(e.target.files);

                let file = iptFile.files[0]

                let fileReader = new FileReader()
                fileReader.readAsDataURL(file)
                fileReader.onload = function(e) {
                    console.log(e.target.result);
                }

            }


        }


    </script>
</head>

<body>
    <input type="file" id="iptFile" name="file"/>
</body>

</html>

示例2

将存入的字符串的blob对象,读出来里面的内容
在这里插入图片描述

ArrayBuffer

我们可以把它理解为特殊的数组,特殊在哪里呢?

  • ArrayBuffer 本身就是一个黑盒,不能直接读写所存储的数据,需要借助以下视图对象来读写
  • TypedArray只是一个概念,实际使用的是那9个对象
    在这里插入图片描述
    在这里插入图片描述

创建buffer

new ArrayBuffer(bytelength)

  • 参数:它接受一个参数,即 bytelength,表示要创建数组缓冲区的大小(以字节为单位。)
    在这里插入图片描述

TypedArray读写buffer

在这里插入图片描述

DataView读写buffer

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

与Blob对比

  1. ArrayBuffer 与 Blob 有啥区别呢?根据 ArrayBuffer 和 Blob 的特性,Blob 作为一个整体文件,适合用于传输;当需要对二进制数据进行操作时(比如要修改某一段数据时),就可以使用 ArrayBuffer。

  2. 通过ArrayBuffer创建Blob,然后通过FileReader读取里面的内容

    在这里插入图片描述

Blob Url & DataUrl

  • 可以使用 File 或 Blob 生成对应的 Url(除了使用现成的file对象,我们也可以用上面的方法,自己创建File对象,然后传进去。)

    • URL.createObjectURL(blob) ; (blob url)
    • FileReader.readAsDataURL(file); (data url)
  • 生成的Url在一些a标签、img标签、iframe标签中可以使用。

示例1

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script>
        window.onload = () => {
            
            let iptFile = document.querySelector('#iptFile')
            let a = document.querySelector('#a')
            let img = document.querySelector('#img')

            iptFile.onchange = (e) => {
                console.log(e.target.files);

                let file = iptFile.files[0]

                let blobUrl = URL.createObjectURL(file) ; 
                console.log(blobUrl);

                a.href = blobUrl
                img.src = blobUrl

            }


        }


    </script>
</head>

<body>
    <input type="file" id="iptFile" name="file"/>
    
    <a href="#" id="a" download>link</a>  <!-- 设置target='_blank'可以打开一个新页面;  
                                                加上download属性后,点击a标签可以下载,
                                                不加download的话,如果浏览器支持查看该文件,将会预览这个文件,
                                                如果不支持查看,将会下载这个文件;
                                                可以使用js模拟点击a标签,来触发下载 -->

    <img src="" id="img" alt="err" style="width:50px;height:50px;">
</body>

</html>

示例2

与上面的效果一致,只不过换成了FileReader
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script>
        window.onload = () => {
            
            let iptFile = document.querySelector('#iptFile')
            let a = document.querySelector('#a')
            let img = document.querySelector('#img')

            iptFile.onchange = (e) => {
                console.log(e.target.files);

                let file = iptFile.files[0]

                let fileReader = new FileReader()
                fileReader.onload = (e) => {
                    let dataUrl = fileReader.result
                    a.href = dataUrl
                    img.src = dataUrl
                }
                fileReader.readAsDataURL(file)

            }


        }


    </script>
</head>

<body>
    <input type="file" id="iptFile" name="file"/>
    
    <a href="#" id="a" download>link</a>  <!-- 设置target='_blank'可以打开一个新页面;  加上download属性后,点击a标签可以下载 -->

    <img src="" id="img" alt="err" style="width:50px;height:50px;">
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/485574.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WIFI密码hacking学习

1 wifite sudo -i 切换到root终端&#xff0c;执行wifite CtrlC 停止WIFI列表扫描 这里选择爆破目标1&#xff0c;他会先监听客户端和wifi的连接的数据包&#xff0c;然后用wordlist-probable.txt里面的字典进行爆破 区别 WPS 是 no 的和yes no会自动化爆破 这种模式默认下…

软件测试行业前景怎么样

软件测试工程师工作好找&#xff0c;但是企业有时却很难招聘到合适的软件测试工程师&#xff0c;这是因为现在企业需要的是自动化测试人才和测试开发人才&#xff01;前些年的手动测试员早已不能满足企业现在的发展需求。 随着人工智能时代的到来&#xff0c;IT行业受到了越来…

从‘孔乙己长衫’现象看社会不公

孔乙已是鲁迅笔下人物&#xff0c;穷困流倒还穿着象征读书人的长衫&#xff0c;迁腐、麻木。最近&#xff0c;大家自我调佩是“当代孔乙己”&#xff0c;学历成为思想负担&#xff0c;找工作时高不成低不就。 认识孔乙己 孔乙己是清朝末年的小贩&#xff0c;生活在贫苦的阶层…

ubuntu22.04安装与配置

目录 一、环境及下载 iso下载 VM配置 二、虚拟机与环境配置 虚拟机开始后的配置 一些工具配置 参考&#xff1a; VMware Workstation Pro 文档 一、环境及下载 iso下载 Download Ubuntu Desktop | Download | Ubuntu 新出了23但是偶数年份稳定支持&#xff0c;所以我…

openai接口调用-如何接入openai获取 api key

openai api key获取 获取 OpenAI API Key 非常简单&#xff0c;您只需要按照以下步骤进行操作: 创建 OpenAI 账户。如果您还没有 OpenAI 账户&#xff0c;请访问 OpenAI 官网&#xff08;http://openai.com/signup&#xff09;并创建一个帐户。登录您的 OpenAI 账户。使用您的…

docker安装ES、kibana和IK分词器

拉取镜像 docker pull elasticsearch:7.4.2 docker pull kibana:7.4.2创建存储数据的目录 mkdir -p /home/lab1018/docker_volume/elasticsearch/config mkdir -p /home/lab1018/docker_volume/elasticsearch/data mkdir -p /home/lab1018/docker_volume/elasticsearch/plugi…

C++-----动态规划

目录 一、动态规划的基本思想 二、设计动态规划法的步骤 三、动态规划问题的特征 4.1 矩阵连乘积问题 4.1.1 分析最优解的结构 4.1.2 建立递归关系 4.1.3 计算最优值 4.1.3 计算最优值 4.1.3 构造最优解 4.2 动态规划算法的基本要素 4.2.1 最优子结构 4.2.2 重叠子问题 …

gRPC结合vcpkg在x64-windows平台visual studio2019 cmake工程里面的应用

这里我们运用vcpkg去下载安装gRPC&#xff0c;进入vcpkg目录后&#xff0c;执行命令&#xff1a;.\vcpkg.exe install grpc:x64-windows grpc在vcpkg里面安装完成后&#xff0c;我们就来使用grpc做一个简单的例子。 gRPC顾名思义&#xff0c;就是google的RPC方案&#xff0c;…

ProtoBuf 编码原理

因为涉及到分布式集群之间的通信&#xff0c;所以来学习了下 ProtoBuf&#xff0c;为什么选择 ProtoBuf 呢&#xff1f;主要还是因为相对于 json , xml 来说&#xff0c;ProtoBuf 传输效率更快&#xff0c;故需要了解下它的编码设计。 首先&#xff0c;每一个 message 进行编码…

科研人必看入门攻略(收藏版)

来源&#xff1a;投稿 作者&#xff1a;小灰灰 编辑&#xff1a;学姐 本文主要以如何做科研&#xff0c;日常内功修炼&#xff0c;常见科研误区&#xff0c;整理日常‘好论文’四个部分做以介绍&#xff0c;方便刚入门的科研者进行很好的规划。 1.如何做科研 1.1 选方向 当我…

【2023年第十一届泰迪杯数据挖掘挑战赛】A题:新冠疫情防控数据的分析 32页和40页论文及实现代码

【2023年第十一届泰迪杯数据挖掘挑战赛】A题&#xff1a;新冠疫情防控数据的分析 32页和40页论文及实现代码 相关链接 &#xff08;1&#xff09;建模方案 【2023年第十一届泰迪杯数据挖掘挑战赛】A题&#xff1a;新冠疫情防控数据的分析 建模方案及python代码详解 &#x…

【初学人工智能原理】【4】梯度下降和反向传播:能改(下)

前言 本文教程均来自b站【小白也能听懂的人工智能原理】&#xff0c;感兴趣的可自行到b站观看。 本文【原文】章节来自课程的对白&#xff0c;由于缺少图片可能无法理解&#xff0c;故放到了最后&#xff0c;建议直接看代码&#xff08;代码放到了前面&#xff09;。 代码实…

《LearnUE——基础指南:开篇—2》——准备工作

目录 0.2.1 UE的获取与创建项目 0.2.2 UE4编辑器界面布局 1. 编辑器介绍 2. 新建蓝图与蓝图拖动 3. 菜单介绍 4. 工具栏介绍 0.2.3 学习资料 0.2.1 UE的获取与创建项目 登录UE官网&#xff1a;www.unrealengine.com 点击“登录”&#xff0c;如果没有账号&#xff0…

自动驾驶——离散系统LQR的黎卡提方程Riccati公式推导与LQR工程化

1.LQR Question Background 之前写过连续系统的黎卡提方程Riccati推导,但是考虑到实际工程落地使用的是离散系统,于是又进行了离散黎卡提方程Riccati的公式推导。 2.Proof of Riccati Equation Formula for Discrete Systems 工程化落地,就是使用公式(2-14)实时计算控制率…

Windows编译安装AzerothCore魔兽世界开源服务端Lua脚本引擎Eluna和防作弊anticheat模块教程

Windows编译安装AzerothCore魔兽世界开源服务端Lua脚本引擎Eluna和防作弊anticheat模块教程 大家好&#xff0c;我是艾西今天和大家聊聊魔兽世界游戏内的脚步以及防作弊模块 Eluna是azerothcore服务端的Lua脚本引擎&#xff0c;可以在原有azerothcore的基础上实现很多拓展以及…

Linux操作系统指令(1)

目录 一、什么是Linux操作系统&#xff1f;二、Linux基本指令12.1 ls指令2.2 pwd指令2.3 cd指令2.4 touch指令2.5 mkdir指令&#xff08;非常重要&#xff09;2.6 rmdir指令 && rm 指令&#xff08;十分重要&#xff09;2.7 man指令&#xff08;非常重要&#xff09;2.…

基于松鼠算法的极限学习机(ELM)回归预测-附代码

基于松鼠算法的极限学习机(ELM)回归预测 文章目录 基于松鼠算法的极限学习机(ELM)回归预测1.极限学习机原理概述2.ELM学习算法3.回归问题数据处理4.基于松鼠算法优化的ELM5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;本文利用松鼠算法对极限学习机进行优化&#xff0c;并…

设计模式-创建型模式-(工厂、简单工厂、抽象工厂)

一、简单工厂模式 上代码 public class FoodFactory {public static Food makeFood(String name) {if (name.equals("noodle")) {Food noodle new LanZhouNoodle();noodle.addSpicy("more");return noodle;} else if (name.equals("chicken")…

Java中的注解和反射

注解 在Java程序中&#xff0c;我们可以在很多地方看到注解&#xff0c;如一下情况: 注解有检查和约束的作用 内置注解 当被Deprecated注解修饰的方法被使用的时候&#xff0c;方法会被画上杠&#xff1a; 元注解 当我们打开一个注解的时候&#xff0c;可以看到以下这些信…

一份标准的软件测试方案模板

第一章 概述 ​ 软件的错误是不可避免的&#xff0c;所以必须经过严格的测试。通过对本软件的测试&#xff0c;尽可能的发现软件中的错误&#xff0c;借以减少系统内部各模块的逻辑&#xff0c;功能上的缺陷和错误&#xff0c;保证每个单元能正确地实现其预期的功能。检测和排…