sus*_*haP 11 javascript html5 textarea drag-and-drop fileapi
我编写了以下代码来检查上传的文件是否存在使用HTML5文件API.
<input type="file" id="myfile">
<button type="button" onclick="addDoc()">Add Document</button>
<p id="DisplayText"></p>
Run Code Online (Sandbox Code Playgroud)
以下JavaScript代码已映射到它如下:
function addDoc() {
var file=document.getElementById("myFile").files[0]; //for input type=file
var reader=new FileReader();
reader.onload = function(e) {}
reader.readAsText(file);
var error = reader.error;
var texte=reader.result;
document.getElementById("DisplayText").innerText=reader.result; /*<p id="DisplayText>*/
}
Run Code Online (Sandbox Code Playgroud)
从本地系统浏览文件后,我尝试在单击之前从文件夹中删除"浏览"文档addDoc()
.单击按钮后我仍然可以看到Filereader.result
不是null并且可以显示所有内容.
有人可以解释Filereader的工作原理吗?一旦浏览文件,FileReader就会被绑定吗?
我们也可以检查系统Readonly Attribute with FileReader是否与Java类似File.canread()
?
有人可以建议吗?我有IE11来测试代码.
gue*_*314 14
FileReader
load
event以.result
异步方式设置值.访问.result
使用load
或loadend
事件.
在<input type="file">
Choose File
或Browse...
UI 处选择文件时,删除本地文件系统中的文件不应影响通过调用返回的File
对象.见2.9.2.可转移对象,6.7.3 DataTransfer接口.FileList
.files
每个
Blob
必须具有内部快照状态,如果存在任何此类底层存储,则必须初始设置为底层存储的状态,并且必须通过该状态保留structured clone
.snapshot state
可以找到File
s的进一步规范性定义.
2.9.8 Blob和FileList对象的Monkey补丁
这个猴子补丁将在适当的时候删除.请参阅w3c/FileAPI问题32.
Blob
对象是cloneable objects
.
给定targetRealm并忽略内存的每个
Blob
对象的[[Clone
]]内部方法必须运行以下步骤:如果是这样
closed
,那么扔一个."DataCloneError"
DOMException
返回的新实例这在targetRealm,对应于同样的基础数据.
给定targetRealm和内存的每个
FileList
对象的[[Clone]]
内部方法 必须运行以下步骤:
让output成为targetRealm中的新
FileList
对象.For each file in this, add ?
[StructuredClone][15](_file, targetRealm, memory_)
to the end of the list ofFile
objects of output.Return output.
At chrome, chromium if read-only permission is set for file at local filesystem and user selects file at <input type="file">
element, where FileReader
is used to read file, an error is thrown at FileReader
, generated from FileReader
progress
event.
If a Blob URL
is set to the same file object, the blob:
URL will not return the the read-only file at request to the 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处显示提示符
Run Code Online (Sandbox Code Playgroud)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显示时呈现通知
Run Code Online (Sandbox Code Playgroud)Could not read the contents of <directory name> Permission denied
*nix OS
When user drops folder at <textarea>
element, where no drop
event is attached, the full path to the folder at user filesystem file:
protocol is exposed. The paths to the files contained within the folder are not also set as .value
; e.g.,
"file:///home/user/Documents/Document/"
Run Code Online (Sandbox Code Playgroud)
When a file is dropped at <textarea>
element, where not drop
event is attached, the full path to the file at user filesystem is set as .value
of <textarea>
; that is,
"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue.txt"
Run Code Online (Sandbox Code Playgroud)
If multiple files are selected and dropped at <textarea>
element, all of the full file paths are set as .value
of <textarea>
, delineated by new line character \n
"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue1.txt"
"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue2.txt"
..
Run Code Online (Sandbox Code Playgroud)
Where an XMLHttpRequest()
is made for the file path and error is logged at console
NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
Run Code Online (Sandbox Code Playgroud)
When set as .src
of an <img>
element with .crossOrigin
set to "anonymous"
the img
error
event handler is called
At call to window.open()
with full path set at first parameter
Error: Access to '"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue.png"' from script denied
Run Code Online (Sandbox Code Playgroud)
4.10.5.1.18. File Upload state (type=file
)
For historical reasons, the
value
IDL attribute prefixes the file name with the string "C:\fakepath\
". Some legacy user agents actually included the full path (which was a security vulnerability). As a result of this, obtaining the file name from thevalue
IDL attribute in a backwards-compatible way is non-trivial.
4.10.5.4. Common <input>
element APIs
filename
On getting, it must return the string "C:\fakepath\" followed by the name of the first file in the list of
selected files
, if any, or the empty string if the list is empty. On setting, if the new value is the empty string, it must empty the list ofselected files
; otherwise, it must throw an "InvalidStateError
"DOMException
.NOTE: This "fakepath" requirement is a sad accident of history. See the example in the File Upload state section for more information.
NOTE: Since
path components
are not permitted in file names in the list ofselected files
, the "\fakepath\
" cannot be mistaken for a path component.
4.10.5.1.18. File Upload state (type=file
)
When an
<input>
element’stype
attribute is in theFile Upload
state, the rules in this section apply.The
<input>
elementrepresents
a list ofselected files
, each file consisting of a file name, a file type, and a file body (the contents of the file).File names must not contain
path components
, even in the case that a user has selected an entire directory hierarchy or multiple files with the same name from different directories. Path components, for the purposes of theFile Upload
state, are those parts of file names that are separated by U+005C REVERSE SOLIDUS character () characters.
Bug report https://bugzilla.mozilla.org/show_bug.cgi?id=1311823
Following comment by Neal Deakin at bug report
I think the steps referred to are:
- Open data:text/html,
- Drag a file from the desktop to the textarea
I can reproduce this on Linux, but not on Windows or Mac.
The hunch above is correct; Linux is including the data as a url and plaintext as well.
dropped files at data:
prototcol data URI
at firefox, and chrome, chromium
data:text/html,<textarea></textarea>
Run Code Online (Sandbox Code Playgroud)
The full path name of file or folder set as .value
of <textarea>
.
Dropping file at data URI
having only textarea
element at chrome, chromium replaces the data URI
with dropped file path at address bar, and loads the dropped file at the same tab, replacing the data URI
with the content of the dropped file.
plnkr http://plnkr.co/edit/ZfAGEAiyLLq8rGXD2ShE?p=preview
html
, javascript
to reproduce issue described above
<!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>
Run Code Online (Sandbox Code Playgroud)
plnkr http://plnkr.co/edit/8Ovw3IlYKI8BYsLhzV88?p=preview
You can use change
event attached to #myfile
element to handle file selection action by user.
Substitute <textarea>
element for <p>
element to display result of load
event from .readAsText()
call.
To display .result
of FileReader
at click
at button
element, set variable text
to reader.result
within load
event of FileReader
at click
event at button
set .textContent
of #DisplayText
element to variable referencing previously set 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>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
20988 次 |
最近记录: |