我知道我不能直接写入他们的机器(出于安全考虑),但我能创建文件并提示他们保存吗?
适用于支持 HTML5 的浏览器的简单解决方案...
function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
form * {
display: block;
margin: 10px;
}
<form onsubmit="download(this['name'].value, this['text'].value)">
<input type="text" name="name" value="test.txt">
<textarea name="text"></textarea>
<input type="submit" value="Download">
</form>
使用方法
download('test.txt', 'Hello world!');
download
属性可以指定文件名;-) - Matěj Pokornýdownload("data.json", data)
,它将按预期工作。 - Carl Smith你可以使用数据URI。 浏览器支持有所不同,请参见维基百科。 例如:
<a href="data:application/octet-stream;charset=utf-16le;base64,//5mAG8AbwAgAGIAYQByAAoA">text file</a>
使用octet-stream可以强制下载提示。否则,文件可能会在浏览器中打开。
对于CSV文件,您可以使用:
<a href="data:application/octet-stream,field1%2Cfield2%0Afoo%2Cbar%0Agoo%2Cgai%0A">CSV Octet</a>
请尝试使用jsFiddle演示。
一个适用于 IE 10+,Firefox 和 Chrome 的示例(无需使用 jQuery 或其他任何库):
function save(filename, data) {
const blob = new Blob([data], {type: 'text/csv'});
if(window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveBlob(blob, filename);
}
else{
const elem = window.document.createElement('a');
elem.href = window.URL.createObjectURL(blob);
elem.download = filename;
document.body.appendChild(elem);
elem.click();
document.body.removeChild(elem);
}
}
请注意,根据您的情况,您可能还需要在删除 elem
后调用URL.revokeObjectURL。根据URL.createObjectURL的文档说明:const url = URL.createObjectURL(blob, { oneTimeOnly: true })
。如果需要,您始终可以保存 Blob 并稍后生成新的 URL。 - Danieldocument.body.appendChild(elem);
之前添加 elem.style.display = 'none';
。 - JamesTheAwesomeDude所有上述例子在Chrome和IE中都能正常工作,但在Firefox中失败。 请考虑在body后附加一个锚点,并在点击后将其删除。
var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob(['Test,Text'], {type: 'text/csv'}));
a.download = 'test.csv';
// Append anchor to body.
document.body.appendChild(a);
a.click();
// Remove anchor from body
document.body.removeChild(a);
a.click()
这一行会抛出“访问被拒绝”的错误,因为它认为blob URL是跨域的。 - Matt我很高兴地使用FileSaver.js。它的兼容性相当好(IE10+和其他所有浏览器),而且非常易于使用:
var blob = new Blob(["some text"], {
type: "text/plain;charset=utf-8;",
});
saveAs(blob, "thing.txt");
使用 Blob:
function download(content, mimeType, filename){
const a = document.createElement('a') // Create "a" element
const blob = new Blob([content], {type: mimeType}) // Create a blob (file-like object)
const url = URL.createObjectURL(blob) // Create an object URL from blob
a.setAttribute('href', url) // Set "a" element link
a.setAttribute('download', filename) // Set download filename
a.click() // Start downloading
}
Blob对象被所有现代浏览器支持。
Blob的支持情况请查看Caniuse支持表:
并且这里有MDN文档
Blob对象表示一个blob,它是一个不可变的、原始数据的类似文件的对象;它们可以被读取为文本或二进制数据...
以下方法适用于IE11+、Firefox 25+和Chrome 30+:
<a id="export" class="myButton" download="" href="#">export</a>
<script>
function createDownloadLink(anchorSelector, str, fileName){
if(window.navigator.msSaveOrOpenBlob) {
var fileData = [str];
blobObject = new Blob(fileData);
$(anchorSelector).click(function(){
window.navigator.msSaveOrOpenBlob(blobObject, fileName);
});
} else {
var url = "data:text/plain;charset=utf-8," + encodeURIComponent(str);
$(anchorSelector).attr("download", fileName);
$(anchorSelector).attr("href", url);
}
}
$(function () {
var str = "hi,file";
createDownloadLink("#export",str,"file.txt");
});
</script>
查看演示:http://jsfiddle.net/Kg7eA/
Firefox 和 Chrome 支持通过数据 URI 进行导航,这使我们可以通过导航到数据 URI 来创建文件,而 IE 为了安全起见不支持此功能。
另一方面,IE 有用于保存 Blob 的 API,可用于创建和下载文件。
document.body.innerHTML +=
`<a id="download" download="PATTERN.json" href="${URL.createObjectURL(new Blob([JSON.stringify("HELLO WORLD", null, 2)]))}"> Click me</a>`
download.click()
download.outerHTML = ""
const stack = {
some: "stuffs",
alot: "of them!"
}
BUTTONDOWNLOAD.onclick = (function(){
let j = document.createElement("a")
j.download = "stack_"+Date.now()+".json"
j.href = URL.createObjectURL(new Blob([JSON.stringify(stack, null, 2)]))
j.click()
})
<button id="BUTTONDOWNLOAD">DOWNLOAD!</button>
额外奖励!下载任何循环对象,避免错误:
TypeError:cyclic object value(Firefox)TypeError:Converting
circular structure to JSON(Chrome和Opera)TypeError:Circular
reference in value argument not supported(Edge)
使用https://github.com/douglascrockford/JSON-js/blob/master/cycle.js
在此示例中,将document
对象下载为json。
/* JSON.decycle */
if(typeof JSON.decycle!=="function"){JSON.decycle=function decycle(object,replacer){"use strict";var objects=new WeakMap();return(function derez(value,path){var old_path;var nu;if(replacer!==undefined){value=replacer(value)}
if(typeof value==="object"&&value!==null&&!(value instanceof Boolean)&&!(value instanceof Date)&&!(value instanceof Number)&&!(value instanceof RegExp)&&!(value instanceof String)){old_path=objects.get(value);if(old_path!==undefined){return{$ref:old_path}}
objects.set(value,path);if(Array.isArray(value)){nu=[];value.forEach(function(element,i){nu[i]=derez(element,path+"["+i+"]")})}else{nu={};Object.keys(value).forEach(function(name){nu[name]=derez(value[name],path+"["+JSON.stringify(name)+"]")})}
return nu}
return value}(object,"$"))}}
document.body.innerHTML +=
`<a id="download" download="PATTERN.json" href="${URL.createObjectURL(new Blob([JSON.stringify(JSON.decycle(document), null, 2)]))}"></a>`
download.click()
这个程序包 js-file-download 来自于 github.com/kennethjiang/js-file-download,它处理浏览器支持的边界情况:
点击查看源代码 以了解它如何使用本页面提到的技术。
yarn add js-file-download
npm install --save js-file-download
import fileDownload from 'js-file-download'
// fileDownload(data, filename, mime)
// mime is optional
fileDownload(data, 'filename.csv', 'text/csv')
这个解决方案直接从tiddlywiki的github存储库中提取而来。我在几乎所有浏览器中使用tiddlywiki,它的表现非常出色:
function(filename,text){
// Set up the link
var link = document.createElement("a");
link.setAttribute("target","_blank");
if(Blob !== undefined) {
var blob = new Blob([text], {type: "text/plain"});
link.setAttribute("href", URL.createObjectURL(blob));
} else {
link.setAttribute("href","data:text/plain," + encodeURIComponent(text));
}
link.setAttribute("download",filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
Github仓库: 下载保存模块