前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >H5 文件预览和下载

H5 文件预览和下载

作者头像
CodecWang
发布2021-12-07 15:39:53
1.8K0
发布2021-12-07 15:39:53
举报
文章被收录于专栏:CodecWangCodecWang
  • Author: Codec.Wang
  • Date: 2020/06/04

今天前端小伙伴遇到这么一个问题:a 标签指向非同源的一个文件,点击后会在浏览器中打开并预览该文件而不是下载它。嗯…很有意思,纪录于此。

同源

你可能跟我一样,网上搜索的大部分解决方案是给 a 标签添加 download 属性,但其实并非所有场景都适用。先来了解下 HTML5 a 标签的 downlaod 属性。

参考MDN,该属性表示让浏览器下载 URL 而不是导航到它。比如项目中有两个文件 (本节源码):

代码语言:javascript
复制
├── index.html
└── config.jsonCopy to clipboardErrorCopied

index 中我写了两个 anchor 标签:

代码语言:javascript
复制
<a href="config.json">不加 download</a>
<a href="config.json" download>加了 download</a>Copy to clipboardErrorCopied

然后启动 web 服务。如果你用 VSCode 的话,可以安装一个插件Live Server。安装好之后,右键 index.html,选择 Open with Live Server,它会自动启动浏览器并访问http://127.0.0.1:5500/index.html,很方便。

不要直接打开 index.html,因为这样使用的是文件 file 协议,而非 http 协议。

分别点击两个 a 标签,你会发现不加 download 的会在浏览器中预览 config.json 文件,而加了 download 就会下载。各浏览器对 download 的兼容性可参考Can I use。另外,也可以给它赋值,表示下载后保存的文件名,如:

代码语言:javascript
复制
<a href="config.json" download='imcute.json'>加了 download 并重命名</a>Copy to clipboardErrorCopied

OK,so far so good。但并没有解决我们的问题,因为很多人忽略了同源这一点,同源表示拥有相同的协议、域名和端口。MDN 上也写的很明确:

代码语言:javascript
复制
此属性仅适用于同源 URL
download only works for same-origin URLs.Copy to clipboardErrorCopied

一般情况下,网站资源就是放在网站服务器上,源相同,所以加上 download 属性没毛病。但我们的文件放在腾讯云对象存储系统 COS 上,显然与网站不同源。

不同源

不同源时就只能通过 JS 来下载了,这就有很多种方法了,非本节的讨论点,大家可自行 Google。

那有没有即使不同源,a 标签照样点击下载的方法呢?有:配置服务端文件的 HTTP Headers。因为 a 标签点击时也是发送了 HTTP 请求,所以可通过设置响应头方式实现。

首先了解下 Content-Disposition,参考MDN,它表示响应的内容以何种形式展示。如果值是 inline,表示是网页的一部分;值为 attachment,表示以附件的形式下载文件。

比如下面两个链接文件内容完全一致,都放在我的对象存储 COS 上面。第二个设置了 Content-Disposition 为 attachment。(腾讯云 COS 请求头的设置方式请参考:上传和下载

  • index.html
代码语言:javascript
复制
<a href="https://techblog-1253540739.cos.ap-chengdu.myqcloud.com/download-instead-preview.json">没设置请求头</a>
<a href="https://techblog-1253540739.cos.ap-chengdu.myqcloud.com/download-instead-preview-attachment.json">设置了请求头</a>Copy to clipboardErrorCopied

运行后分别点击这两个 a 标签。第一个还是预览,第二个就直接下载了。搞定!

配置成 attachment 时,也可以添加文件名:

代码语言:javascript
复制
Content-Disposition: attachment; filename="imcute.json"Copy to clipboardErrorCopied

此时,如果 a 标签也加了 download='config.json'的属性,将优先使用请求头中配置的,即 imcute.json

PDF

对于 pdf 文件,Chrome 和基于 Chromium 的 Edge 浏览器在设置中提供了一个是否始终外部打开的选项。打开后,无论服务端有没有设置 Content-Disposition,文件都会下载。

  • 打开浏览器设置,搜索 pdf:

引用

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 同源
  • 不同源
  • PDF
  • 引用
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档