前端文件下载(一)

本文,我们将通过案例,讲解如何进行超链接文件下载。

假设我们返回了一个文件的超链接,比如 http://localhost:3000/test.txt,我们可以怎么下载呢?

演示环境(Main)

Google Chrome: 版本 116.0.5845.187(正式版本) (arm64)

Node: v14.18.1

Vscode:插件 - Live Server

同源

我们先来了解下同源的情况下下载超链接文件

我们通过 koa 开启一个 SSR 的应用:

javascript 复制代码
const Koa = require('koa');
const Router = require('koa-router');
const ejs = require('ejs');
const fs = require('fs');
const path = require('path');
const static = require('koa-static');

const app = new Koa();
const router = new Router();

// static file
const staticPath = path.join(__dirname, 'public');
app.use(static(staticPath));

// template
const template = fs.readFileSync('template.ejs', 'utf-8');

router.get('/', async (ctx) => {

  const fileName = 'test.txt';
  const fileUrl = path.join(fileName);

  // simulated data
  const templateData = {
    title: 'SSR Page',
    content: 'Hello, Jimmy!',
    fileUrl: fileUrl
  };

  const html = await ejs.render(template, templateData);
  // return
  ctx.body = html;
});

app.use(router.routes());

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

上面我们开启了一个服务,将文件数据提供给 ejs 模版文件。

HTMLa 标签

添加模版文件内容:

ejs 复制代码
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
  </head>
  <body>
    <h1 id="app"><%= content %></h1>
    <a href="<%= fileUrl %>" download="file.txt">Download File: <%= fileUrl %></a>
  </body>
</html>

运行服务后,整个页面渲染如下:

我们触发下载:

是的,原先的文件名是 text.txt,我们在设定 <a> 标签的时候,使用 download 属性,浏览器会自动下载文件,且我们更改了下载的名称(给 download 设定了值为 file.txt)。当然,我们不指定 download 属性值,则会以默认的文件名保存文件,如下:

通过 JS 构建 a 标签

我们更改下 ejs 模版文件的内容:

html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
  </head>
  <body>
    <h1 id="app"><%= content %></h1>
    <button id="download">Download File: <%= fileUrl %></button>
    <script>
      (function(){
        let downloadBtn = document.getElementById('download');
        downloadBtn.addEventListener('click', function() {
          const link = document.createElement('a'); // create
          link.href = '<%= fileUrl %>';
          link.setAttribute('download', 'file');
          document.body.appendChild(link); // append
          link.click(); // click
          document.body.removeChild(link); // remove 
        })
      })()
    </script>
  </body>
</html>

点击下载按钮,会通过 javascript 创建一个 a 标签,然后设定其 url 链接和 download 属性值改变下载文件名。如果你不想更改下载的文件名,可以设置设置为 link.setAttribute('download', '') 即可。

跨域

⚠️ 如果读者对同源和跨域还不是很了解,可以前往我之前的文章 【案例】同源策略 - CORS 处理 学习

那么,上面说到的同源中的两种方法,是否可以在跨域中使用到呢?我们来尝试下:

我们使用 Koa 开启一个服务,有返回文件超链接的接口:

javascript 复制代码
const Koa = require('koa');
const Router = require('koa-router');
const fs = require('fs');
const path = require('path');
const static = require('koa-static');

const app = new Koa();
const router = new Router();

// static file
const staticPath = path.join(__dirname, 'public');
app.use(static(staticPath));

router.get('/', async (ctx) => {

  const fileName = 'test.txt';
  const fileUrl = path.join(fileName);

  // simulated data
  const data = {
    title: 'Hello, Jimmy!',
    fileUrl: fileUrl
  };
  // return
  ctx.body = {
    data
  };
});

app.use(router.routes());

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

启动服务,我们访问 http://localhost:3000/test.txt,则会看到返回信息:

为了方便看到自动吊起浏览器的下载,我们更改下文件为:

javascript 复制代码
// const fileName = 'test.txt'; // -
const fileName = 'test.txt.zip'; // +

HTMLa 标签

我们另起项目,添加下 html 文件:

html 复制代码
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Download Client</title>
</head>
<body>
  <a href="http://localhost:3000/test.txt.zip">Download File</a>
</body>
</html>

开启服务,在端口号 5500 上监听。点击上面的 a 标签,那么就可以自动跳转下载该文件。那么,我们要更改下载的文件名称,可以?

我们来添加 download 属性值为 download='custom',发现并不能更改文件名:

通过 JS 构建 a 标签

这个方法也能实现文件的下载,因为都是通过控制 a 标签。那么,它能不能改变文件名呢?是不能的。

我们更改下 html 文件:

html 复制代码
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Download Client</title>
</head>
<body>
  <button id="download">Download File</button>
  <script>
    (function(){
      let downloadBtn = document.getElementById('download');
      downloadBtn.addEventListener('click', function() {
        const link = document.createElement('a'); // create
        link.href = 'http://localhost:3000/test.txt.zip';
        link.setAttribute('download', 'custom');
        document.body.appendChild(link); // append
        link.click(); // click
        document.body.removeChild(link); // remove 
      })
    })()
  </script>
</body>
</html>

我们设定了自定义的文件名 link.setAttribute('download', 'custom');,但是没有效果。如下:

总结

本文主要是通过介绍 a 标签的方法来下载超链接文件 ,介绍了用单纯的 htmljavascript 的方法来操作。两者的效果都是一样。最后,我们得出的结果如下:

  • 同源和跨域下,都可以使用 a 标签对超链接文件进行预览或者下载
  • 同源下,超链接文件 可以通过 a 标签 download 属性值更改下载文件的名称;跨域下,超链接文件不能被更改文件名称
  • 超链接文件 ,通过a 标签,调用起浏览器默认的下载,可以在自带的浏览器上看到下载的进度。页面上监听不到下载的进度。

读者对 超链接文件 下载有什么见解,可以评论区留言,大家一起成长~

相关推荐
2501_915918411 小时前
Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析
前端·低代码·ios·小程序·uni-app·编辑器·iphone
程序员爱钓鱼1 小时前
Go语言实战案例 — 工具开发篇:实现一个图片批量压缩工具
后端·google·go
程序员的世界你不懂2 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
索迪迈科技2 小时前
网络请求库——Axios库深度解析
前端·网络·vue.js·北京百思可瑞教育·百思可瑞教育
gnip2 小时前
JavaScript二叉树相关概念
前端
一朵梨花压海棠go3 小时前
html+js实现表格本地筛选
开发语言·javascript·html·ecmascript
attitude.x3 小时前
PyTorch 动态图的灵活性与实用技巧
前端·人工智能·深度学习
β添砖java3 小时前
CSS3核心技术
前端·css·css3
ChinaRainbowSea3 小时前
7. LangChain4j + 记忆缓存详细说明
java·数据库·redis·后端·缓存·langchain·ai编程
舒一笑3 小时前
同步框架与底层消费机制解决方案梳理
后端·程序员