本文,我们将通过案例,讲解如何进行超链接文件下载。
假设我们返回了一个文件的超链接,比如 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
模版文件。
纯 HTML
中 a
标签
添加模版文件内容:
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'; // +
纯 HTML
中 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>
<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
标签的方法来下载超链接文件 ,介绍了用单纯的 html
和 javascript
的方法来操作。两者的效果都是一样。最后,我们得出的结果如下:
- 同源和跨域下,都可以使用
a
标签对超链接文件进行预览或者下载 - 同源下,超链接文件 可以通过
a
标签download
属性值更改下载文件的名称;跨域下,超链接文件不能被更改文件名称 - 超链接文件 ,通过
a
标签,调用起浏览器默认的下载,可以在自带的浏览器上看到下载的进度。页面上监听不到下载的进度。
读者对 超链接文件 下载有什么见解,可以评论区留言,大家一起成长~