如何在不使用具有下载属性或服务器的 <a> 元素的情况下下载文件?
How to download a file without using <a> element with download attribute or a server?
根据caniuse the download
attribute of <a>
element is supported at Microsoft Edge build 10547+, but not IE or Safari。
如何在不使用具有 download
属性集或服务器的 <a>
元素或服务器的情况下下载文件对象?
有多种触发下载的方法。以下是一些:
使用表格:
<form method="get" action="mydoc.doc">
<button type="submit">Download</button>
</form>
使用javascript:
<button type="submit" onclick="window.open('mydoc.doc')">Download</button>
您可以使用 data URI
data:[<mediatype>][;base64],<data>
representation of file either created manually or utilizing FileReader()
, .readAsDataURL()
, with MIME
type set to application/octet-stream
、encodeURIComponent()
、window.open()
<script>
var file = "data:application/octet-stream,"
+ encodeURIComponent("<!DOCTYPE html>"
+ "<html><body>"
+ "<div>abc</div>"
+ "</body></html>");
var saveFile = window.open(file, "_self");
</script>
<script>
var blob = new Blob(["abc"], {type:"text/plain"});
var reader = new FileReader();
reader.addEventListener("load", function(e) {
// replace existing `MIME` type with `application/octet-stream`
var file = "data:application/octet-stream;"
+ e.target.result.split(/;/)[1];
var saveFile = window.open(file, "_self");
});
reader.readAsDataURL(blob)
</script>
虽然我支持@LeoFarmer 的回答,但我想提供两个 "hackable" 方法:
如果文件很小,可以使用a
和href='data:[<mediatype>][;base64],<data>'
。
这可以让您在 mediatype
中添加内容配置,模拟 HTTP header。这种 hack 也不像人们希望的那样便携。
对于中小型文件,可以使用AJAX下载文件,然后use the Javascript File API to prompt for file saving(API不支持保存,但是很容易将数据转换为数据 URL).
如果您想避开 Javascript 文件 API,您可以尝试模拟锚点击,如 suggested here.
同样,正如 Leo Farmer 所指出的,这些解决方案不能保证浏览器不会在新选项卡中打开文件而不是将其保存到磁盘,但我认为可以肯定地说所有用户将能够优雅地降级为 cmd+S
或 ctrl+S
键盘快捷键:-)
您可以使用下载属性和 jquery 来完成此操作。 ie 和 safari/ios 不支持下载属性。所以你可以使用 jquery 来做到这一点
$('.download').click(function(e) {
e.preventDefault(); //stop the browser from following
window.location.href = 'uploads/file.doc';
});
<a href="no-script.html" class="download">Download</a>
Use FileSaver.js
它支持所有常用的浏览器。
只需包括:
<script type="text/javascript" src="FileSaver.min.js"></script>
并像这样使用它:
var file = new File(["Hello, world!"], "hello world.txt", {type: "text/plain;charset=utf-8"});
saveAs(file);
注:
要使其在 Safari < 6、Opera < 15 和 FireFox < 20 中也能正常工作,您需要包含 Blob.js 作为依赖项。
如果您使用的是服务器端,请遵循表单提交机制来呈现页面。
在 MVC 中我们可以使用下面的代码
Html
@using (Html.BeginForm("GetAttachment", "User", FormMethod.Post))
{
<button type="submit">Download</button>
}
MVC 控制器
public ActionResult GetAttachment()
{
string filename = "File.pdf";
string filepath = AppDomain.CurrentDomain.BaseDirectory + "/Path/To/File/" + filename;
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
string contentType = MimeMapping.GetMimeMapping(filepath);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = filename,
Inline = true,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(filedata, contentType);
}
根据caniuse the download
attribute of <a>
element is supported at Microsoft Edge build 10547+, but not IE or Safari。
如何在不使用具有 download
属性集或服务器的 <a>
元素或服务器的情况下下载文件对象?
有多种触发下载的方法。以下是一些:
使用表格:
<form method="get" action="mydoc.doc">
<button type="submit">Download</button>
</form>
使用javascript:
<button type="submit" onclick="window.open('mydoc.doc')">Download</button>
您可以使用 data URI
data:[<mediatype>][;base64],<data>
representation of file either created manually or utilizing FileReader()
, .readAsDataURL()
, with MIME
type set to application/octet-stream
、encodeURIComponent()
、window.open()
<script>
var file = "data:application/octet-stream,"
+ encodeURIComponent("<!DOCTYPE html>"
+ "<html><body>"
+ "<div>abc</div>"
+ "</body></html>");
var saveFile = window.open(file, "_self");
</script>
<script>
var blob = new Blob(["abc"], {type:"text/plain"});
var reader = new FileReader();
reader.addEventListener("load", function(e) {
// replace existing `MIME` type with `application/octet-stream`
var file = "data:application/octet-stream;"
+ e.target.result.split(/;/)[1];
var saveFile = window.open(file, "_self");
});
reader.readAsDataURL(blob)
</script>
虽然我支持@LeoFarmer 的回答,但我想提供两个 "hackable" 方法:
如果文件很小,可以使用
a
和href='data:[<mediatype>][;base64],<data>'
。这可以让您在
mediatype
中添加内容配置,模拟 HTTP header。这种 hack 也不像人们希望的那样便携。对于中小型文件,可以使用AJAX下载文件,然后use the Javascript File API to prompt for file saving(API不支持保存,但是很容易将数据转换为数据 URL).
如果您想避开 Javascript 文件 API,您可以尝试模拟锚点击,如 suggested here.
同样,正如 Leo Farmer 所指出的,这些解决方案不能保证浏览器不会在新选项卡中打开文件而不是将其保存到磁盘,但我认为可以肯定地说所有用户将能够优雅地降级为 cmd+S
或 ctrl+S
键盘快捷键:-)
您可以使用下载属性和 jquery 来完成此操作。 ie 和 safari/ios 不支持下载属性。所以你可以使用 jquery 来做到这一点
$('.download').click(function(e) {
e.preventDefault(); //stop the browser from following
window.location.href = 'uploads/file.doc';
});
<a href="no-script.html" class="download">Download</a>
Use FileSaver.js
它支持所有常用的浏览器。
只需包括:
<script type="text/javascript" src="FileSaver.min.js"></script>
并像这样使用它:
var file = new File(["Hello, world!"], "hello world.txt", {type: "text/plain;charset=utf-8"});
saveAs(file);
注: 要使其在 Safari < 6、Opera < 15 和 FireFox < 20 中也能正常工作,您需要包含 Blob.js 作为依赖项。
如果您使用的是服务器端,请遵循表单提交机制来呈现页面。 在 MVC 中我们可以使用下面的代码
Html
@using (Html.BeginForm("GetAttachment", "User", FormMethod.Post))
{
<button type="submit">Download</button>
}
MVC 控制器
public ActionResult GetAttachment()
{
string filename = "File.pdf";
string filepath = AppDomain.CurrentDomain.BaseDirectory + "/Path/To/File/" + filename;
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
string contentType = MimeMapping.GetMimeMapping(filepath);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = filename,
Inline = true,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(filedata, contentType);
}