整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

原生Javascript实现下载base64图片

原生Javascript实现下载base64图片

景:在实际生产中,程序员会遇到导出图片的需求,通常情况下,前端工程师只要将页面上canvas转成base64的字符串,通过调用后端接口,将base64的字符串上传,由后台工程师生成文件。但是,遇到刚入门的菜鸟后端时,这一切就不是那么顺利了。俗话说,求人不如求己,靠人不如靠己。这点小功能,前端工程师通过base64转Blob的方式也可以做到。


下面直接上代码:

第一步:先把base64字符串转成Blob文件

const base64ToBlob = (code)=> {
  const lists = code.split(';base64,')
  const contentType = lists[0].split(':')[1]
  const raw = window.atob(lists[1])
  const rawLength = raw.length
  const arraryBuffer = new ArrayBuffer(rawLength)
  let uInt8Array = new Uint8Array(arrayBuffer)
  for(let i = 0; i < rawLength; i++) {
    uInt8Array[i] = raw.charCodeAt(i)
  }
  return new Blob([uInt8Array], {type: contentType})
}

第二步:通过生成a标签,设置a标签的href属性,模拟点击事件触发下载功能

const downloadFile = (content, fileName) => {
  const aLink = document.createElement('a')
  const blob = base64ToBlob(content)
  const evt = document.createEvent('HTMLEvents')
  evt.initEvent('click', true, true)
  aLink.download = fileName // 设置下载文件名称
  aLink.href = URL.createObjectURL(blob)
  const options={
    bubbles: true,
    cancelable: true,
    view: window
  }
  const mouseEvent = new MouseEvent('click', options)
  aLink.dispatchEvent(mouseEvent)
}

最后,完成!

文章来聊聊浏览器到底是如何对待下载资源的,比如说 JS、CSS、字体、图片等文件。
CSS、JS 文件冤家路窄
HTML 在解析的过程中遇到同步的 script 会卡住 DOM 解析这个知识点我相信读者们应该都知道。
<!DOCTYPE html> <html lang="en"> <body> <script>console.log(1)</script> <div>1</div> </body> </html>
上述代码中,HTML 遇到 <script>console.log(1)</script> 代码就会停止 DOM 解析了。当然现代浏览器不是说就这样停住啥也不干了,会有个 preload scanner 去扫描底下的文件,然后根据文件类型去制定优先级(这个下面再说)。
上面举得例子是内联代码,如果是一个 JS 文件的话,那么就得等这个 JS 文件下完以后执行代码才行。
但是一般我们文件结构不会那么单一,CSS 文件也肯定是有的。因为 JS 不仅能动 DOM 也能改 style,所以如果遇到 script 之前还有别的 CSS 文件的话,浏览器还得等 CSS 文件下完以后再去执行 JS。
所以说不只是 JS 会阻塞 DOM 解析,CSS 也会。
当然我想现在应该很少再有人直接写同步的 script 了吧。
文件同时遇到,那会同时开始下载嘛?
举个例子,在可以同时下载多个文件的情况下,浏览器在 HTML、CSS 文件中解析到了 img、font、background-image 资源,那么们会同时开始下载嘛?
答案是不会!
这里只有 img 会最先开始下载,其它两块内容都得等到 layout 以后才会开始下载。不信的话我们来看图:
这里以 font 为例


图中右下角框出来的是字体文件,上面是 CSS 文件,字体是从 CSS 文件中得知需要去加载的。
大家可以在图中发现 CSS 文件早早开始下载解析了,但是 font 文件迟迟未开始下载,直到 FP 指标即将出现的时候才开始下载动作,这个时间点是在 layout 完成以后。
图中是以掘金为例,大家可以多试试别的网站,应该能发现是符合预期的。
那么读者可能会有个疑问,按照这个逻辑意思是说能用 img 的都用 img,因为background-image 不是马上开始下载的?道理是这个道理,但是还是得分情况来说,如果图片出现的位置不是首屏,用 background-image 也没啥问题,当然给 img 用上懒加载也能解决问题。
那么到底文件的优先级是如何的?
如果大家有使用过 Performance 测试网站性能的话,可以在 Network 那栏里 hover 下载的资源,此时你能发现资源有优先级的显示。


从图中大家可以发现 CSS 和字体资源的优先级的最高的,JS 文件有高有低(这和类型有关),图片、svg 的优先级为低。
这部分的优先级是指某个时间点上的优先级,而不是适应于整个周期。对于 CSS 文件优先级最高还是挺好理解的,毕竟 JS 文件依赖于 CSS 文件,更加详细的内容大家可以参考 从Chrome源码看浏览器如何加载资源 中的「3. 资源优先级」内容。
网络协议才是最大元凶
浏览器要下载资源,TCP 协议肯定得用上,但是 TCP 协议天生就是一个慢的东西。
先得握手,然后慢开始算法,就和我们用迅雷下载东西一样,带宽很大没用,速度都是得爬升上去的。如果再加个 HTTPS 的话,还得再多个 TLS 的握手。
然后说回 HTTP1.1 协议。Chrome 只支持同个 domain 同时并发 6 个请求,所以在之前的协议中一堆请求都得 block 住等之前的下载完成。
当然现在不同了,HTTP2 的概念基本大家都知道了,没见过猪跑但吃过猪肉,对于这块的知识点聊上几句没啥问题。什么多路复用,header 合并、二进制帧啥的。
得利于 HTTP2 协议中的多路复用,我们不再被浏览器的六个并发所限制,所有同一个 domain 上的请求都能跑在复用的六个网络通道上,下载耗时瞬间减少了几个量级,但是大家有没有考虑过这个 HTTP2 到底是如何对待这些资源的?
如何分配它们的优先级?依赖?带宽或者别的?毕竟一堆资源占用同一个网络通道,那么到底该谁先下载,谁享有的带宽多点都是需要协调的。否则假如一堆图片占用了大部分带宽,其他 CSS、JS 文件下的很慢的话,就会影响整个网页的性能了。
比如说我现在需要下载 CSS、JS、图片和字体这些文件。举个例子在这些文件中我希望 CSS 文件能最先开始下载,并且能分配到的带宽多点;JS 文件呢可以等 CSS 文件下完再去下;其他文件呢优先级比 CSS 文件低点,但是也能够享受到带宽去进行下载。
这个需求我们可以通过二进制帧去实现。HTTP2 协议共存在十个二进制帧,其中你可以通过 HEADERS 帧分配新的优先级,也可以通过 PRIORITY 帧更改优先级。
对于流的优先级,我们可以通过两个方式来实现调整:

  • 当我们调整流的依赖时,就可以实现让 JS 文件等待 CSS 文件下载完毕以后再开始
  • 当我们调整流的 weight 时,就可以实现带宽的分配,让某些资源能更快地进行下载


如图所示(丑了点)。第一排的文件开始一起下载,weight 相加为 20,那么通过计算可得 CSS 文件享有带宽的一半,其他各占有 1 / 4,JS 文件得等 CSS 完成以后才开始。
那么该如何设置这些东西呢?当然得服务端支持啦,一般都指 CDN 服务商了。
最后

查找了很多资料,如有遗漏,还请见谅。文中如果有误,还望及时指出,感谢

学习Java之前,我们需要了解一定的前端知识。毕竟页面才是用户真正看到的,而且也是体现Java后端逻辑结果的地方。

学习HTML后,能够制作界面美观大方的静态网站(更复杂的功能需要JavaScript脚本一起来实现)。


HTML制作的网页。

所需要的Html开发工具,可使用Hbuilder。

下载路径:https://www.dcloud.io/

第一次写文章,不知道链接会不会被屏蔽,如果看不到可以自行百度,直接搜索Hbuilder,进入官网下载安装,安装完打开软件后,点击暂不登陆,你懂的(免费使用)。

网页一般使用Chrome,IE的兼容性比较差,学习建议使用Chrome。

下载路径:https://www.google.cn/chrome/

作者推荐的学习用软件,都为免费,放心下载使用。

一、在Hbuilder中如何来创建页面

1、文件->新建->web项目

2、给项目起名(也可以修改路径,命名用英文或者拼音缩写,用中文可能开发会出错)

Hbulider创建项目


3、完成

4、右击新建的项目:新建->HTML文件

5、为新的文件重命名,以html作为后缀

6、完成


Hbuilder创建Html文件


7、选择页面,点击在浏览器中运行按钮


在浏览器中运行按钮


以下新手笔试或者面试容易考

HTML是HyperText Markup Language缩写,意为超文本标记语言,“超文本”就是指页面内可以包含图片、链接,甚至音乐、程序等非文字元素。

特点:

1、简易性

2、可扩展性

3、平台无关性

4、通用性


HTML的结构

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title></title>
	</head>

	<body>
		<h1>Hello Java</h1>
		<h2>Hello Html</h2>
	</body>

</html>

HTML的结构详解:(了解即可,一般开发软件会自动生成,如不生成,那就找个会生成的软件,复制黏贴)

<!DOCTYPE html>:文件类型声明,H5中就这么一种写法。

<html>:告知浏览器其自身是一个 HTML 文档,限定了文档的开始点和结束点

<head>:文档的头部描述了文档的各种属性和信息,包括文档的标题、字符集等信息。绝大多数文档头部包含的数据都不会真正作为内容显示给读者。在head中可以定义样式,引用样式,也可以定义脚本和引用脚本

<body>:文档的主体部分,包含文档的所有内容(比如文本、超链接、图像、表格和列表等等。),body部分的内容一般就是直接呈现给用户的部分

网页中的乱码问题:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="gb2312">
		<title></title>
	</head>
	<body>
		<h1>Hello Java</h1>
		<h2>Hello Html</h2>
		你好
	</body>
</html>

运行以上代码,可以在网页中看到,“你好”两个字为乱码。这是<meta charset="gb2312">搞的鬼。

当文件本身的字符集编码以与网页head部分指定的字符集编码不一致时,就会产生乱码问题,可以在head部分的meta标签中指定和文件一样的字符集编码来解决这一问题。<meta charset="utf-8" />

从执行上面的代码也可以看出,html是按从上到下的顺序来显示的。

下一篇内容:Html各种标签的认识和使用。