前端文件下载(一)

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

假设我们返回了一个文件的超链接,比如 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 标签,调用起浏览器默认的下载,可以在自带的浏览器上看到下载的进度。页面上监听不到下载的进度。

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

相关推荐
GetcharZp5 小时前
玩转 Linux 机器视觉:手把手带你搞定 Ubuntu 下海康工业相机 C++ SDK
后端
橙子家5 小时前
浏览器缓存之【基础键值存储】:Local storage 和 Session storage
前端
星星在线8 小时前
MusicFree:一个「All in One」的个人音乐服务器,让听歌回归简单
前端·后端
IT_陈寒9 小时前
Redis的SETNX并发问题让我加了三天班
前端·人工智能·后端
demo007x9 小时前
Docling 文档转换以及技术架构分析
前端·后端·程序员
京东云开发者10 小时前
京东市民服务又“上新”!这次是黑龙江“龙易办”
前端
袋鱼不重10 小时前
我的神奇同事,AI 用多了居然写了个 Open In Codex
前端·后端·ai编程
用户83562907805110 小时前
使用 Python 操作 Word 内容控件
后端·python
像我这样帅的人丶你还10 小时前
啥? 前端也要会干Java?🛵🛵🛵
后端
竹林81810 小时前
Web3表单签名验证:我用 wagmi 和 ethers 给 DApp 加了一个“免密登录”,踩坑记录全在这了
javascript