优秀的编程知识分享平台

网站首页 > 技术文章 正文

深入细聊前端下载总结「干货」(前端下载链接)

nanyue 2024-08-10 18:46:21 技术文章 8 ℃


作者:luffyZh

转发链接:https://github.com/luffyZh/frontend-download-sample

前言

自己整理的一些项目中遇到过的关于上传和下载的一些Demo,大前端系列(也就是纯前端 + node端完成的下载,只要获取到数据下载工作全是前端来做),仅供各位看官参考,避免踩坑,即插即用,欢迎fork和star,为这个仓库添砖加瓦~(P.S. 个人认为如果没写过上传下载其实还是挺麻烦的,这个基本能覆盖大部分场景了~)

在此之前,小编也整理发布过几篇关于前端下载的优质文章:

谈谈前端关于文件上传下载那些事【实践】

前端下载文件的5种方法的对比

JavaScript实现图片合成下载

vue+element实现excel中的信息批量导入和导入模板的下载

如何实现一个下载进度条/播放进度条「案例」

一文了解文件上传全过程(1.8w字深度解析)「前端进阶必备」

更多的JavaScript实践项目学习文章,请见本篇文章底部,有惊喜

包括内容

  • 纯前端下载基于a标签location && iframeFileSaver ---> [推荐]
  • node端下载先下载到本地,再下载到浏览器直接流向浏览器下载 [推荐]

frontend-download-sample:https://github.com/luffyZh/frontend-download-sample

在这里怕大家没有耐心看下去,放一个强烈推荐的filesaver的Demo动态图

写在前面

上传和下载个人认为在前端开发时稍微复杂一丢丢,需要额外处理一些事情而不是直接获取数据渲染页面,所以想着把平时遇到过的一些场景整理一下分享出来,大牛绕过,不喜勿喷~我平时在项目中接触的也就是一些上传图片,上传安装包,下载图片,下载安装包以及整理数据生成excel文件下载下来。暂时还没有接触过其他类型的,所以本项目可能有一定的局限性,只是给大家提供一种思路或者方案,有其他想法欢迎评论~

纯前端下载形式

顾名思义,纯前端实现,也就是不依赖于任何后端。不过这种方式有一定的局限性,比如下载类型,写法,数据形式等等。但是既然不依赖与后端,在可接受范围之内还是很推荐使用的,毕竟简单啊~

基于a标签下载

说到简单,那么最简单的就是这个了。那就是基于<a>标签的下载文件方式,真的是超级简单。使用方法如下:

href: 文件的绝对/相对地址
download: 文件名(可省略,省略后浏览器自动识别源文件名)
<a href='xxx.jpg' download='file.jpg'>下载jpg图片</a>

那么既然这么简单,那肯定是存在问题的。


上面这张图片是官方提供的兼容性,目前只有FireFox和Chrome支持download属性。至少这两个对于开发者来说不陌生,占有量也很大,所以也还可以吧,但是接下来我又尝试了一下这两个浏览器的兼容性情况。


上面这张,是FireFox浏览器最新版,可以看到点击下载文件会弹出一个对话框,之后点击保存文件才可以进行下载,同时只能下载不能被浏览器打开的文件类型,如图片、文本文件、html文件这种可以被打开的文件,是无法被下载的直接在浏览器进行预览。


上面这张,是Chrome最新版,与FireFox相同,对于图片文件和文本文件这种可以被浏览器打开的文件不会被下载,而excel和安装包这种文件是可以被直接下载的,无需进行任何二次确认操作。

那么能不能不让浏览器预览图片(或pdf或txt文件)?

肯定能啊~为什么呢?其实a标签的href属性还可以接受除了相对和绝对路径之外的其他形式Url,比如下面我们要用到的DataUrl和BlobUrl。我们使用这种形式,就可以让浏览器不预览而直接下载图片了,当然了操作起来更麻烦一些了就。

  • DataUrl
 // 首先,图片转base64
 // ./util.js
 
 // html页面,将a标签href属性动态赋值为dataUrl
 <a id='downloadDataUrl' class="button is-dark">下载data:Url图片</a>
 ...
 <script>
  const image = new Image();
  image.setAttribute("crossOrigin",'Anonymous');
  image.src = '../files/test-download.png' + '?' + new Date().getTime();
  image.onload = function() {  
    const imageDataUrl = image2base64(image);  
    const downloadDataUrlDom = document.getElementById('downloadDataUrl');
    downloadDataUrlDom.setAttribute('href', imageDataUrl);
    downloadDataUrlDom.setAttribute('download', 'download-data-url.png');
    downloadDataUrlDom.addEventListener('click', () => {
      console.log('下载文件');
    });
  }  
</script>

如下图,可以看到不再是预览文件,而是直接下载文件了。这里面有一些坑,比如canvas.toDataUrl的一些问题以及解决办法,我就不多说了,大家自己去看看。

  • BlobUrl 整体逻辑更复杂了,首先 文件 -> base64(dataUrl) -> blob -> blobUrl
 // 第一步:首先需要将文件转换成base64,方法上面一样
 // 第二步:将base64转换成blob数据
 // DataUrl 转 Blob数据
    function dataUrl2Blob(dataUrl) {
      var arr = dataUrl.split(','),
          mime = arr[0].match(/:(.*?);/)[1],
          bStr = atob(arr[1]),
          n = bStr.length,
          unit8Array = new Uint8Array(n);
      while (n--) {
        unit8Array[n] = bStr.charCodeAt(n);
      }
      return new Blob([unit8Array], { type: mime });
    } 
 // 第三步: 将blob数据转换成BlobUrl
 URL.createObjectURL(imageBlobData);
 
 // 完整代码
  <a id='downloadBlobUrl' class="button is-danger">下载blobUrl图片</a>
  ...
  const image2 = new Image();  
  image2.setAttribute("crossOrigin",'Anonymous');
  image2.src = '../files/test-download.png' + '?' + new Date().getTime();
  image2.onload = function() {  
    const imageDataUrl = image2base64(image2);
    const imageBlobData = dataUrl2Blob(imageDataUrl);
    const downloadDataUrlDom = document.getElementById('downloadBlobUrl');
    downloadDataUrlDom.setAttribute('href', URL.createObjectURL(imageBlobData));
    downloadDataUrlDom.setAttribute('download', 'download-data-url.png');
    downloadDataUrlDom.addEventListener('click', () => {
      console.log('下载文件');
    });
  }

【总结】: Chrome在兼容性上更胜一筹,但是二者总体来说都存在一些问题,不能直接下载图片和文本文件,但是毕竟这么简洁,你没进行任何多余的操作,存在问题合情合理。同时,上面的几种方式也看到了,dataUrl适合图片的下载,而blobUrl虽然要麻烦一些,但是对于文本文件的下载还是非常有用的,你可以直接把要下载的内容转换成blob数据,然后转换成blobUrl进行下载,适用于.txt,.json等文件类型

【建议】: 如果下载的需求是特殊文件类型,如安装包,excel文件,并且可以存放在CDN又一个可访问的url链接。那么这种方式非常完美,当然,如果你可以接受上面所说的兼容性问题。同时如果你采用dataUrl或者blobUrl的时候,由于存在很多问题,比如cors之类的事情,建议可以使用这种方法,但是需要配合后端,也就是后端帮你转换好,你直接拿转换好的url来下载就行了。

location.href 和 iframe下载

上面这两种非常好理解,就是在另一个窗口或者当前地址栏地址指向下载链接,下载链接要求是dataUrl或者blobUrl。只不过,iframe是更高级一些,也就是可以帮助我们做到无闪下载,作为开发者大家应该都懂,我就不多BB了。


从上面这个动图,可以看出来,这个方法其实还不如<a>标签下载,为什么这么说呢,会因为a标签方法虽然会预览浏览器可以预览的文件,但是如果进行适当转化,还是能进行下载的。但是location这种方法无论是dataUrl还是blobUrl,只要是图片、文本文件以及pdf等所有浏览器可以打开的文件,都会直接给你预览,只能下载那些浏览器不支持预览的那些文件。所以Just so so了。

iframe封装无闪现下载方法

本质很简单,就是不让当前浏览器窗口执行下载操作,而是另开一个iframe进行文件的下载。但是这个iframe是用户不可见的~这里需要注意,如果是纯前端,建议不要进行图片等浏览器可打开的文件下载,因为隐藏iframe里打开你也看不到,也就是他的问题还是上面那些。可以进行excel、zip以及各种资源文件的下载。

// 无闪现下载excel
function download(url) {
  const iframe = document.createElement('iframe');
  iframe.style.display = 'none';
  function iframeLoad() {
    console.log('iframe onload');
    const win = iframe.contentWindow;
    const doc = win.document;
    if (win.location.href === url) {
      if (doc.body.childNodes.length > 0) {
        // response is error
      }
      iframe.parentNode.removeChild(iframe);
    }
  }
  if ('onload' in iframe) {
    iframe.onload = iframeLoad;
  } else if (iframe.attachEvent) {
    iframe.attachEvent('onload', iframeLoad);
  } else {
    iframe.onreadystatechange = function onreadystatechange() {
      if (iframe.readyState === 'complete') {
        iframeLoad;
      }
    };
  }
  iframe.src = '';
  document.body.appendChild(iframe);

  setTimeout(function loadUrl() {
    iframe.contentWindow.location.href = url;
  }, 50);
}

如果你在项目里需要进行无闪现下载,什么都不用做,只需要调用 download(url),即可进行无闪现下载~亲测可用

使用FileSaver强大的前端下载插件 -> 【强烈推荐】

FileSaver的下载方式完全是前端(Client-Side)的下载方式,它是基于Blob进行下载的,当然因为是基于前端下载,所以浏览器下载会有一定的限制,也就是Blob数据的大小不能过大,看看官网给的相关参数:

可以看到,基本对于支持的浏览器来说,大小可以达到 500MB+,应该已经可以满足大部分需求了。如果文件确实很大,官网给出了替代方案StreamSaver,没去研究过这个,不过作者既然推荐可能也很好,感兴趣的可以去看看。

前面讲到了,FileSaver是基于Blob的,其实并不准确,可以看一下官网:


其实它支持Blob、File和Url进行下载,但是如果基于url了我也没必要用FileSaver了,那个<a>标签也挺好的是不?然后基于File一般都是特定场景,比如上传的时候,才会用到FileReader之类的API,说实话我也没怎么用过,都是封装的,所以这里也不做介绍。开头也说过了,希望小伙伴可以给这个仓库添加东西啊,可以增加自己的下载Demo到这里,非常欢迎

所以我这篇文章讨论的下载,就是基于Blob。首要工作就是将文件转换成Blob数据。下面几个例子都是这样:

FileSaver ---- 下载canvas

  • 依赖 - canvas-to-blob

这个Demo简单点的话其实可以直接用canvas画一个image在页面上,然后再进行下载,但是那样还不如直接下载图片了,所以麻烦一些,写一个canvas白板,然后下载我们自己绘制的内容并且起名字进行下载。


 // 生成下载的文件名 
 function generateFilename(id, mime) {
    const filename = document.getElementById(id).value || document.getElementById(id).placeholder;
    return filename + mime;
  }
  const canvasDownloadDom = document.getElementById('download-canvas');
  canvasDownloadDom.addEventListener('click', () => {
    const canvas = document.getElementById('canvas');
    const filename = generateFilename('canvasName', '.png');
    if (canvas.toBlob) {
      // 调用方法将canvas转换成blob数据
      canvas.toBlob(
          function (blob) {
            // 调用FileSaver方法下载
            saveAs(blob, filename);
          },
          'image/png'
      );
    }   
  });

代码非常简单,感兴趣的小伙伴可以去看看每个插件内部的代码。我这里就是应用级别的示例了。

FileSaver ---- 直接下载图片

直接下载图片就是将图片转换成Blob数据,然后进行下载。


// FileSaver 下载文件
  const image = new Image();  
  image.setAttribute("crossOrigin",'Anonymous');
  image.src = '../files/test-download.png' + '?' + new Date().getTime();
  image.onload = function() {  
    const imageDataUrl = image2base64(image);
    const imageBlobData = dataUrl2Blob(imageDataUrl);
    const downloadImageDom = document.getElementById('download-image');
    downloadImageDom.addEventListener('click', () => {
      saveAs(imageBlobData, 'test-download.png');
    });
  }

这代码就更简单了,就是前面<a>标签下载Blob数据的代码,数据转换是一样的,只不过下载使用的是FileSaver。

FileSaver ---- 下载文本文件

下载文本文件就更容易了,因为JavaScript支持直接将字符串构造成Blob对象。

const textBlob = new Blob(["your target string"], {type: "text/plain;charset=utf-8"});


下载下来的txt文件长这样:


 // FileSaver 下载文本文件
  const txtDownloadDom = document.getElementById('download-txt');
  txtDownloadDom.addEventListener('click', () => {
    const textarea = document.getElementById('textarea');
    const filename = generateFilename('textareaName', '.txt');
    const textBlob = new Blob([textarea.value], {type: "text/plain;charset=utf-8"});
    saveAs(textBlob, filename);
  });

FileSaver ---- 下载Excel文件(搭配js-xlsx)

前面的都相对简单一些,但是其实除了下载图片,可能平时也没什么业务场景需要到。接下来要说的可是所有商务系统几乎都能遇到的了,那就是 —— 下载报表,也就是Excel文件。这里面就使用FileSaver配合js-xlsx来进行excel的纯前端下载工作~

下载下来的文件长这样:

// 下载excel文件
  const excelDownloadDom = document.getElementById('download-excel');
  excelDownloadDom.addEventListener('click', () => {
    // 找到table节点调用方法转化数据
    const wb = XLSX.utils.table_to_book(document.querySelector('#table-excel'));
    // 生成excel数据
    const wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' });
    try {
      // 下载excel文件
      saveAs(new Blob([wbout], { type: 'application/octet-stream' }), 'table-excel.xlsx');
    } catch (e) {
      if (typeof console !== 'undefined') console.log(e, wbout)
    }
  });

这里面我只是介绍如何用FileSaver在前端下载excel文件,至于js-xlsx如何将数据转化成excel的这里不做介绍。我只是简单的调用了js-xlsx的将table转成excel的方法, js-xlsx还有很多高级功能,有这方面需求的去看看官方文档js-xlsx就好了~

node端配合下载(大前端)

带后端支持的下载就要轻松很多了,为什么呢,因为上面所有纯前端下载都可以与后端进行配合使用,也就是后端生成对应的下载链接下载数据返回给前端,前端根据设计方案按需使用上面几种方式下载,肯定能下载成功。那么node端配合下载肯定是要下载点不一样的东西了——那就是文件流

有很多场景,那就是大文件不是存在于CDN,而是以文件流的形式存放在内存。那么就没有对应的下载链接,下载对应文件的时候,后端返回的就是文件流。而node里为我们提供Stream支持各种流操纵。所以我们可以在node端直接进行文件的下载。

先下载到本地再从浏览器下载

  • fs下载Excel 下载下来的Excel文件:
// 第一步:构造数据
const data = [
  [1, 2, 3],
  [true, false, null, 'sheetjs'],
  ['foo', 'bar', new Date('2014-02-19T14:30Z'), '0.3'],
  ['baz', null, 'qux'],
];
// 第二步:生成excel的Buffer数据
const buffer = xlsx.build([{ name: 'mySheetName', data }]);

// 第三步:写文件到本地
const tmpExcel = `filename.xlsx`;

fs.writeFileSync(
  tmpExcel,
  buffer,
  {
    encoding: 'utf8',
  },
  err => {
    if (err) throw new Error(err);
  },
);
// 第四步:从本地读取文件下载到浏览器
res.setHeader('Content-disposition', `attachment; filename="${tmpExcel}"`);
res.setHeader('Content-Type', 'application/octet-stream');
// pipe generated file to the response
fs.createReadStream(tmpExcel).pipe(res);
// 下载完成后删除文件
fs.unlinkSync(tmpExcel);

下载excel在node端我使用的不是js-xlsx而是node-xlsx,因为它构造数据非常简单,功能也很强大,十分推荐大家使用~

  • fs下载文件

这里场景不是很容易描述,因为Demo我都是将文件放到本地目录的,所以我读取本地文件再下载到本地再下载到浏览器,我这不是有病吗。。。一般场景是文件以文件流的形式存在内存里,然后我们通过接口下载到本地再从本地下载到浏览器。或者是上传文件保存到本地,然后再从本地进行相关操作,这里就不写示例代码了。

node端直接流向浏览器下载【推荐】

node端,我使用的是express框架(其他的框架也都一样),如果你是文件流直接过来的,那么直接调用res.attachment()下载文件流,如果是文件path,那么可以直接res.download(filepath)。具体见demo

  • 直接下载Excel

上面过程其实多经历了一步,为什么呢?因为拿到buffer之后我们其实就可以直接将buffer流向浏览器下载了~这里我用的是Express框架,直接使用res.attachment()方法就可以了。


下载下来的文件


与上面一模一样我就不展示了。

按照我的理解,第二种明显要比第一种好很多为什么还要列出第一种呢?我个人觉得,第一种虽然一定会牺牲一定的性能,但是先下载到本地就可以对文件进行一些校验,比如文件是否完整,文件名之类的是否合法,还有些时候的场景可能。毕竟不是所有的下载场景都像Demo这样简单。存在即合理,所以还是都罗列出来。

// 第一步:构造数据
const data = [
  [1, 2, 3],
  [true, false, null, 'sheetjs'],
  ['foo', 'bar', new Date('2014-02-19T14:30Z'), '0.3'],
  ['baz', null, 'qux'],
];
// 第二步:生成buffer
const buffer = xlsx.build([{ name: 'mySheetName', data }]);
// 第三步:直接下载
res.status(200)
  .attachment('bufferExcel.xlsx')
  .send(buffer);
// 上面下载代码等同于下面这段代码(nodejs原生代码)
res.setHeader('Content-disposition', `attachment; filename="${tmpExcel}"`);
res.setHeader('Content-Type', 'application/octet-stream');
res.end(buffer);
  • 直接下载文件流

这里我把文件安装包放在本地了,然后我先读取文件内容同时下载到浏览器~

// 第一种,已知文件路径直接下载
try {
  const packagePath = 'static/download/iTerm2-3_2_5.zip';
  res.download(path.join(rootDir, packagePath));
} catch (e) {
  console.error(e);
}
// 第二种,读取本地文件流向浏览器
res.setHeader('Content-disposition', `attachment; filename="download-package.zip"`);
res.setHeader('Content-Type', 'application/octet-stream');
fs.createReadStream(path.join(rootDir, packagePath), 'utf-8').pipe(res);

request

最后给大家安利一个将Stream API使用到极致的Http(Https)请求库 —— request。

// 不加这一行下载下来的文件没有后缀
res.setHeader('Content-disposition', 'attachment; filename=node-v8.14.0-linux-x64.tar.gz');
request('https://npm.taobao.org/mirrors/node/v8.14.0/node-v8.14.0-linux-x64.tar.gz')
  .pipe(res);

这里我为了省时间,就用了自己以前搭过的一个脚手架Next-Antd-Scafflod,直接在这里写的Demo。你可以理解我在打广告,你点进去给个star我也不介意。

地址:https://github.com/luffyZh/next-antd-scaffold

总结

看到这里无论怎么样都十分感谢了,总结的不怎么样,可以理解为自我总结文章吧。如果对大家能有那么一点点启发那就更好了。最后如果有兴趣或者有疑问,可以留言或者直接去仓库里提~

github:https://github.com/luffyZh/frontend-download-sample

推荐JavaScript学习相关文章

细品西瓜播放器功能分析(上)「实践」

细品西瓜播放器功能分析(下)「实践」

细聊50道JavaScript基础面试题「附答案」

webpack4主流程源码解说以及动手实现一个简单的webpack(上)

webpack4主流程源码解说以及动手实现一个简单的webpack(下)

细聊前端架构师的视野

细聊应用场景再谈防抖和节流「进阶篇」

前端埋点统一接入方案实践

细聊微内核架构在前端的应用「干货」

一种高性能的Tree组件实现方案「干货」

进击的JAMStack

前后端全部用 JS 开发是什么体验(Hybrid + Egg.js经验分享)上

前后端全部用 JS 开发是什么体验(Hybrid + Egg.js经验分享)中

前后端全部用 JS 开发是什么体验(Hybrid + Egg.js经验分享)下

一文带你搞懂 babel-plugin-import 插件(上)「源码解析」

一文带你搞懂 babel-plugin-import 插件(下)「源码解析」

JavaScript常用API合集汇总「值得收藏」

推荐10个常用的图片处理小帮手(上)「值得收藏」

推荐10个常用的图片处理小帮手(下)「值得收藏」

JavaScript 中ES6代理的实际用例

12 个实用的前端开发技巧总结

一文带你搞懂搭建企业级的 npm 私有仓库

教你如何使用内联框架元素 IFrames 的沙箱属性提高安全性?

细说前端开发UI公共组件的新认识「实践」

细说DOM API中append和appendChild的三个不同点

细品淘系大佬讲前端新人如何上王者「干货」

一文带你彻底解决背景跟随弹窗滚动问题「干货」

推荐常用的5款代码比较工具「值得收藏」

Node.js实现将文字与图片合成技巧

爱奇艺云剪辑Web端的技术实现

我再也不敢说我会写前端 Button组件「实践」

NodeX Component - 滴滴集团 Node.js 生态组件体系「实践」

Node Buffers 完整指南

推荐18个webpack精美插件「干货」

前端开发需要了解常用7种JavaScript设计模式

浅谈浏览器架构、单线程js、事件循环、消息队列、宏任务和微任务

了不起的 Webpack HMR 学习指南(上)「含源码讲解」

了不起的 Webpack HMR 学习指南(下)「含源码讲解」

10个打开了我新世界大门的 WebAPI(上)「实践」

10个打开了我新世界大门的 WebAPI(中)「实践」

10个打开了我新世界大门的 WebAPI(下)「实践」

「图文」ESLint 在中大型团队的应用实践

Deno是代码的浏览器,你认同吗?

前端存储除了 localStorage 还有啥?

Javascript 多线程编程?的前世今生

微前端方案 qiankun(实践及总结)

「图文」V8 垃圾回收原来这么简单?

Webpack 5模块联邦引发微前端的革命?

基于 Web 端的人脸识别身份验证「实践」

「前端进阶」高性能渲染十万条数据(时间分片)

「前端进阶」高性能渲染十万条数据(虚拟列表)

图解 Promise 实现原理(一):基础实现

图解 Promise 实现原理(二):Promise 链式调用

图解 Promise 实现原理(三):Promise 原型方法实现

图解 Promise 实现原理(四):Promise 静态方法实现

实践教你从零构建前端 Lint 工作流「干货」

高性能多级多选级联组件开发「JS篇」

深入浅出讲解Node.js CLI 工具最佳实战

延迟加载图像以提高Web网站性能的五种方法「实践」

比较 JavaScript 对象的四种方式「实践」

使用Service Worker让你的 Web 应用如虎添翼(上)「干货」

使用Service Worker让你的 Web 应用如虎添翼(中)「干货」

使用Service Worker让你的 Web 应用如虎添翼(下)「干货」

前端如何一次性处理10万条数据「进阶篇」

推荐三款正则可视化工具「JS篇」

如何让用户选择是否离开当前页面?「JS篇」

JavaScript开发人员更喜欢Deno的五大原因

仅用18行JavaScript实现一个倒数计时器

图文细说JavaScript 的运行机制

一个轻量级 JavaScript 全文搜索库,轻松实现站内离线搜索

推荐Web程序员常用的15个源代码编辑器

10个实用的JS技巧「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(一)「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(二)「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(三)「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(四)「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(五)「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(六)「值得收藏」

深入JavaScript教你内存泄漏如何防范

手把手教你7个有趣的JavaScript 项目-上「附源码」

手把手教你7个有趣的JavaScript 项目-下「附源码」

JavaScript 使用 mediaDevices API 访问摄像头自拍

手把手教你前端代码如何做错误上报「JS篇」

一文让你彻底搞懂移动前端和Web 前端区别在哪里

63个JavaScript 正则大礼包「值得收藏」

提高你的 JavaScript 技能10 个问答题

JavaScript图表库的5个首选

一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法

可视化的 JS:动态图演示 - 事件循环 Event Loop的过程

教你如何用动态规划和贪心算法实现前端瀑布流布局「实践」

可视化的 js:动态图演示 Promises & Async/Await 的过程

原生JS封装拖动验证滑块你会吗?「实践」

如何实现高性能的在线 PDF 预览

细说使用字体库加密数据-仿58同城

Node.js要完了吗?

Pug 3.0.0正式发布,不再支持 Node.js 6/8

纯JS手写轮播图(代码逻辑清晰,通俗易懂)

JavaScript 20 年 中文版之创立标准

值得收藏的前端常用60余种工具方法「JS篇」

箭头函数和常规函数之间的 5 个区别

通过发布/订阅的设计模式搞懂 Node.js 核心模块 Events

「前端篇」不再为正则烦恼

「速围」Node.js V14.3.0 发布支持顶级 Await 和 REPL 增强功能

深入细品浏览器原理「流程图」

JavaScript 已进入第三个时代,未来将何去何从?

前端上传前预览文件 image、text、json、video、audio「实践」

深入细品 EventLoop 和浏览器渲染、帧动画、空闲回调的关系

推荐13个有用的JavaScript数组技巧「值得收藏」

前端必备基础知识:window.location 详解

不要再依赖CommonJS了

犀牛书作者:最该忘记的JavaScript特性

36个工作中常用的JavaScript函数片段「值得收藏」

Node + H5 实现大文件分片上传、断点续传

一文了解文件上传全过程(1.8w字深度解析)「前端进阶必备」

【实践总结】关于小程序挣脱枷锁实现批量上传

手把手教你前端的各种文件上传攻略和大文件断点续传

字节跳动面试官:请你实现一个大文件上传和断点续传

谈谈前端关于文件上传下载那些事【实践】

手把手教你如何编写一个前端图片压缩、方向纠正、预览、上传插件

最全的 JavaScript 模块化方案和工具

「前端进阶」JS中的内存管理

JavaScript正则深入以及10个非常有意思的正则实战

前端面试者经常忽视的一道JavaScript 面试题

一行JS代码实现一个简单的模板字符串替换「实践」

JS代码是如何被压缩的「前端高级进阶」

前端开发规范:命名规范、html规范、css规范、js规范

【规范篇】前端团队代码规范最佳实践

100个原生JavaScript代码片段知识点详细汇总【实践】

关于前端174道 JavaScript知识点汇总(一)

关于前端174道 JavaScript知识点汇总(二)

关于前端174道 JavaScript知识点汇总(三)

几个非常有意思的javascript知识点总结【实践】

都2020年了,你还不会JavaScript 装饰器?

JavaScript实现图片合成下载

70个JavaScript知识点详细总结(上)【实践】

70个JavaScript知识点详细总结(下)【实践】

开源了一个 JavaScript 版敏感词过滤库

送你 43 道 JavaScript 面试题

3个很棒的小众JavaScript库,你值得拥有

手把手教你深入巩固JavaScript知识体系【思维导图】

推荐7个很棒的JavaScript产品步骤引导库

Echa哥教你彻底弄懂 JavaScript 执行机制

一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧

深入解析高频项目中运用到的知识点汇总【JS篇】

JavaScript 工具函数大全【新】

从JavaScript中看设计模式(总结)

身份证号码的正则表达式及验证详解(JavaScript,Regex)

浏览器中实现JavaScript计时器的4种创新方式

Three.js 动效方案

手把手教你常用的59个JS类方法

127个常用的JS代码片段,每段代码花30秒就能看懂-【上】

深入浅出讲解 js 深拷贝 vs 浅拷贝

手把手教你JS开发H5游戏【消灭星星】

深入浅出讲解JS中this/apply/call/bind巧妙用法【实践】

手把手教你全方位解读JS中this真正含义【实践】

书到用时方恨少,一大波JS开发工具函数来了

干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)

手把手教你JS 异步编程六种方案【实践】

让你减少加班的15条高效JS技巧知识点汇总【实践】

手把手教你JS开发H5游戏【黄金矿工】

手把手教你JS实现监控浏览器上下左右滚动

JS 经典实例知识点整理汇总【实践】

2.6万字JS干货分享,带你领略前端魅力【基础篇】

2.6万字JS干货分享,带你领略前端魅力【实践篇】

简单几步让你的 JS 写得更漂亮

恭喜你获得治疗JS this的详细药方

谈谈前端关于文件上传下载那些事【实践】

面试中教你绕过关于 JavaScript 作用域的 5 个坑

Jquery插件(常用的插件库)

【JS】如何防止重复发送ajax请求

JavaScript+Canvas实现自定义画板

Continuation 在 JS 中的应用「前端篇」


作者:luffyZh

转发链接:https://github.com/luffyZh/frontend-download-sample

最近发表
标签列表