FileReader load事件.result异步设置值。访问.result使用load或loadend事件。
当在<input type="file"> Choose File或Browse...UI处选择了文件时,在本地文件系统中删除文件不应影响调用返回的File对象。见2.9.2。可传输对象,6.7.3 DataTransfer 接口。FileList.files
4. Blob 接口和二进制数据
每个都Blob必须有一个内部快照 state,它必须最初设置为底层存储的状态(如果存在任何此类底层存储),并且必须通过 保存
structured clone。snapshot state可以找到Files 的进一步规范定义。
2.9.8 Blob 和 FileList 对象的 Monkey 补丁
这个猴子补丁将在适当的时候删除。请参阅w3c/FileAPI 问题 32。
Blob对象是cloneable objects.
每个Blob对象的 [[ Clone]] 内部方法,给定 targetRealm 并忽略内存,必须运行以下步骤:
如果是closed,则抛出一个."DataCloneError" DOMException
在targetRealm 中返回this 的一个新实例,对应于相同的底层数据。
FileList对象是可克隆的对象。
每个FileList对象的[[Clone]]内部方法,给定
targetRealm和memory,必须运行以下步骤:
让output成为targetRealm 中的一个新FileList对象。
对于每一个文件,在此,补充的吗?[StructuredClone][15](_file, targetRealm, memory_)到输出File对象列表的末尾。
返回输出。
在 webkit 和 firefox 浏览器中选择只读文件或文件夹
在 chrome 中,如果在本地文件系统中为文件设置了只读权限,并且用户在用于读取文件的<input type="file">元素处选择文件,则在 chrome 处FileReader抛出错误FileReader,由FileReader progress事件生成。
如果 aBlob URL设置为相同的文件对象,则blob:URL 将不会在请求时将只读文件返回给Blob URL.
选择文件夹权限设置为只读的文件夹
铬、铬
在铬,其中铬webkitdirectory属性被设置和文件夹被选择具有只读许可FileList .length的event.target.files返回0; event.target.files.webkitGetAsEntry()未被调用,"No file chosen"在 处呈现<input type="file"> shadowDOM。当文件夹放置在<input type="file">或droppable属性设置的元素时,只读文件夹的目录.name和.path显示在drop event.dataTransfer。
当用户将文件或文件夹放置<textarea>在没有drop附加beforeunload事件的元素上时,将调用事件并在 UI 上显示提示
Do you want to leave this site?
Changes you made may not be saved.
<Stay><Leave> // <buttons>
火狐
在 firefox 版本 47.0b9 中,allowdirs属性设置在<input type="file">元素处,用户单击"Choose folder.." <input>,文件夹.name和.path父文件夹的可访问.then()链接到event.target.getFilesAndDirectories()。递归迭代Directory条目时,不返回所选文件夹中包含的文件或文件夹;返回一个空字符串。
如果用户单击"Choose file..." <input>并选择了没有设置只读权限的文件夹,则单击文件管理器中的文件夹时,将列出该文件夹中的文件。
如果选择了设置只读权限的文件夹,则会alert()在 UI 显示时呈现通知
Could not read the contents of <directory name>
Permission denied
错误,安全问题
*nix 操作系统
当用户<textarea>在没有drop附加事件的元素上放置文件夹时,将file:公开用户文件系统协议中文件夹的完整路径。文件夹中包含的文件的路径也未设置为.value; 例如,
"file:///home/user/Documents/Document/"
当一个文件在下降<textarea>元件,其中不drop附连时,在用户文件系统中的文件的完整路径被设置为.value的<textarea>; 那是,
"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue.txt"
如果选择了多个文件,并在下降<textarea>元素,所有的完整的文件路径设置为.value中<textarea>,通过新行字符划定\n
"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue1.txt"
"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue2.txt"
..
XMLHttpRequest()文件路径和错误记录在何处console
NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
当设置为.src一个的<img>与元素.crossOrigin集合到"anonymous"该img error事件处理程序被调用
在调用时window.open()在第一个参数中设置完整路径
Error: Access to '"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue.png"' from script denied
规格
4.10.5.1.18。文件上传状态 ( type=file)
例 16
由于历史原因,valueIDL 属性在文件名前加上字符串“ C:\fakepath\”。一些旧的用户代理实际上包含了完整路径(这是一个安全漏洞)。因此value,以向后兼容的方式从IDL 属性获取文件名并非易事。
4.10.5.4. 公共<input>元素 API
文件名
在获取时,它必须返回字符串 "C:\fakepath\" 后跟列表中第一个文件的名称(selected
files如果有),或者如果列表为空则返回空字符串。设置时,如果新值是空字符串,则必须清空selected files; 否则,它必须抛出一个 " InvalidStateError"
DOMException。
注意:这个“fakepath”要求是历史上的一个可悲的意外。有关更多信息,请参阅文件上传状态部分中的示例。
注意:由于path components的列表中的文件名中不允许出现selected files“ \fakepath\”,因此不能将其误认为是路径组件。
4.10.5.1.18。文件上传状态 ( type=file)
路径组件
当<input>元素的type属性处于File Upload
状态时,本节中的规则适用。
所述<input>元件represents的列表selected files,每个文件由一个文件名,文件类型,以及文件主体(该文件的内容)。
文件名不得包含path components,即使用户选择了整个目录层次结构或来自不同目录的多个同名文件。就状态而言,路径组件File Upload是文件名中由 U+005C REVERSE SOLIDUS 字符 () 字符分隔的那些部分。
错误报告https://bugzilla.mozilla.org/show_bug.cgi?id=1311823
在数据 URI 的 <textarea> 处删除文件
遵循Neal Deakin在错误报告中的评论
我认为提到的步骤是:
- 打开数据:文本/html,
- 从桌面拖一个文件到textarea
我可以在 Linux 上重现这个,但不能在 Windows 或 Mac 上重现。
上面的预感是正确的;Linux 也将数据作为 url 和纯文本包含在内。
在 Firefox 的data:prototcoldata URI和 chrome、chrome 中删除文件
data:text/html,<textarea></textarea>
火狐
文件或文件夹设置为全路径名.value的<textarea>。
铬、铬
在 chromedata URI中只有textarea元素时删除文件,chrome 替换data URI地址栏中的删除文件路径,并在同一选项卡中加载删除的文件,替换data URI为删除文件的内容。
plnkr http://plnkr.co/edit/ZfAGEAiyLLq8rGXD2ShE?p=preview
html,javascript重现上述问题
<!DOCTYPE html>
<html>
<head>
<style>
body {
height: 400px;
}
textarea {
width: 95%;
height: inherit;
}
</style>
<script>
window.onload = function() {
var button = document.querySelector("#myfile + button");
var input = document.getElementById("myfile");
var display = document.getElementById("DisplayText");
var text = null;
function readFullPathToFileOnUserFileSystem(e) {
var path = e.target.value;
console.log(path);
var w = window.open(path, "_blank");
var img = new Image;
img.crossOrigin = "anonymous";
img.onload = function() {
document.body.appendChild(this);
}
img.onerror = function(err) {
console.log("img error", err.message)
}
img.src = path;
var request = new XMLHttpRequest();
request.open("GET", path.trim(), true);
request.onload = function() {
console.log(this.responseText)
}
request.error = function(err) {
console.log(err.message)
}
request.send();
}
display.addEventListener("input", readFullPathToFileOnUserFileSystem);
input.addEventListener("change", addDoc);
input.addEventListener("progress", function(event) {
console.log("progress", event)
});
button.addEventListener("click", handleText)
function addDoc(event) {
var mozResult = [];
function mozReadDirectories(entries, path) {
console.log("dir", entries, path);
return [].reduce.call(entries, function(promise, entry) {
return promise.then(function() {
console.log("entry", entry);
return Promise.resolve(entry.getFilesAndDirectories() || entry)
.then(function(dir) {
console.log("dir getFilesAndDirectories", dir)
return dir
})
})
}, Promise.resolve())
.catch(function(err) {
console.log(err, err.message)
})
.then(function(items) {
console.log("items", items);
var dir = items.filter(function(folder) {
return folder instanceof Directory
});
var files = items.filter(function(file) {
return file instanceof File
});
if (files.length) {
console.log("files:", files, path);
mozResult = mozResult.concat.apply(mozResult, files);
}
if (dir.length) {
console.log(dir, dir[0] instanceof Directory, dir[0]);
return mozReadDirectories(dir, dir[0].path || path);
} else {
if (!dir.length) {
return Promise.resolve(mozResult).then(function(complete) {
return complete
})
}
}
})
.catch(function(err) {
console.log(err)
})
};
console.log("files", event.target.files);
if ("getFilesAndDirectories" in event.target) {
return (event.type === "drop" ? event.dataTransfer : event.target)
.getFilesAndDirectories()
.then(function(dir) {
if (dir[0] instanceof Directory) {
console.log(dir)
return mozReadDirectories(dir, dir[0].path || path)
.then(function(complete) {
console.log("complete:", complete);
event.target.value = null;
});
} else {
if (dir[0] instanceof File && dir[0].size > 0) {
return Promise.resolve(dir)
.then(function(complete) {
console.log("complete:", complete);
})
} else {
if (dir[0].size == 0) {
throw new Error("could not process '" + dir[0].name + "' directory" + " at drop event at firefox, upload folders at 'Choose folder...' input");
}
}
}
}).catch(function(err) {
console.log(err)
})
}
var reader = new FileReader();
reader.onload = function(e) {
text = reader.result;
console.log("FileReader.result", text);
button.removeAttribute("disabled");
}
reader.onerror = function(err) {
console.log(err, err.loaded, err.loaded === 0, file);
button.removeAttribute("disabled");
}
reader.onprogress = function(e) {
console.log(e, e.lengthComputable, e.loaded, e.total);
}
reader.readAsArrayBuffer(file);
}
function handleText() {
// do stuff with `text`: `reader.result` from `addDoc`
display.textContent = text;
button.setAttribute("disabled", "disabled");
// set `text` to `null` if not needed or referenced again
text = null;
}
}
</script>
</head>
<body>
<input type="file" id="myfile" webkitdirectory directory allowdirs>
<button type="button" disabled>Add Document</button>
<br>
<br>
<textarea id="DisplayText"></textarea>
</body>
</html>
plnkr http://plnkr.co/edit/8Ovw3IlYKI8BYsLhzV88?p=preview
您可以使用change附加到#myfile元素的事件来处理用户的文件选择操作。
<textarea>用<p>element替换element以显示调用load事件的结果.readAsText()。
要显示.result的FileReader在click在button元件,组可变text至reader.result内load的事件FileReader在click事件在button一组.textContent的#DisplayText元素,以可变参考先前设置的reader.result。
<!DOCTYPE html>
<html>
<style>
body {
height: 400px;
}
textarea {
width:95%;
height: inherit;
}
</style>
<head>
<script>
window.onload = function() {
var button = document.querySelector("#myfile + button");
var input = document.getElementById("myfile");
var display = document.getElementById("DisplayText");
var text = null;
input.addEventListener("change", addDoc);
button.addEventListener("click", handleText)
function addDoc(event) {
var file = this.files[0]
var reader = new FileReader();
reader.onload = function(e) {
text = reader.result;
button.removeAttribute("disabled");
}
reader.onerror = function(err) {
console.log(err, err.loaded
, err.loaded === 0
, file);
button.removeAttribute("disabled");
}
reader.readAsText(event.target.files[0]);
}
function handleText() {
// do stuff with `text`: `reader.result` from `addDoc`
display.textContent = text;
button.setAttribute("disabled", "disabled");
// set `text` to `null` if not needed or referenced again
text = null;
}
}
</script>
</head>
<body>
<input type="file" id="myfile" accept="text/*">
<button type="button" disabled>Add Document</button><br><br>
<textarea id="DisplayText"></textarea>
</body>
</html>