本文介绍了记住并重新填充文件输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我有一个网站,允许用户多次上传文件进行处理。目前我有一个单一的文件输入,但我希望能够记住用户的选择,并在屏幕上显示它。 我想知道怎么做是用户选择一个文件后,我会记住他们的选择,并重新显示文件输入与预先选择的页面上重新加载的文件。我只需要知道如何记住和重新填充文件输入。 我也接受不使用文件输入的方法(如果可能的话)。 我正在使用JQuery 解决方案好的,您要记住和重新填充文件输入 记住他们的选择,并重新显示文件输入与文件预先选择在页面重新加载.. 而在评论我的以前的回答是,你并没有真正打开替代品:抱歉,没有Flash和Applets,只是javscript和/或文件输入,可能是拖放。 我在浏览(相当一些)重复的问题时注意到了( 1 , 2 , 3 等),几乎所有其他的答案都符合:不,你不能,这将是一个安全问题,可选的后面是一个简单的概念或代码举例说明安全风险。然而,一个顽固的骡子(不一定是一个坏的东西)可能会认为这些答案是:不,因为我这样说,确实是不同的东西:不,这里是不允许它的规格。所以,这是我第三次也是最后一次尝试回答你的问题(我引导你到了水坑,我带你到河边,现在我推动你的来源,但我不能让你喝)。 $ b 编辑3: 你想要做的事实际上曾经在 RFC1867 第3.4节: $ b 事实上, HTML 4.01 spec section 17.4.1 指定: 这是一个现实的安全/隐私风险:恶意网站(所有者/利用者)可以获得用户主目录的路径(个人资料,帐户,cookie ,注册表的用户部分,历史记录,收藏夹,桌面等位于已知的常量位置),当典型的非技术Windows用户将从 C:\ Documents and Settings \\ \\ [用户名] \我的文档\我的图片\kinky_stuff\image.ext 。 我甚至没有谈论传输数据的风险(甚至通过https加密)或者安全的存储这些数据! 这样,越来越多的可选浏览器开始关注其中一个最古老被证明的安全措施:共享需要知道的信息。 绝大多数网站不需要知道文件路径,所以他们只显示文件名(+扩展名)。 到IE8发布的时候,MS决定跟随竞争并添加一个URLAction选项,名为Include local directory上传文件的路径,默认情况下,这个文件被设置为禁用的一般互联网区域(在受信任的区域中启用)。 $ b 一个小小的破坏(主要是针对IE环境进行了优化),其中各种自定义代码和专有控件都无法获取上传文件的文件名:它们被硬编码以期望包含完整路径的字符串一个d提取最后一个反斜杠后面的部分(如果你幸运的话,也可以是正斜杠)。 沿着HTML5, 和你已经阅读上面,'模式文件名'指定: ? : $ b $ b $因此,事件的 dataTransfer 属性具有类似数组的属性文件(就像输入字段类型=文件 这是一个类似数组的 FileList对象,我们刚才已经知道FileList是只读的 .. $ b FileList包含对用户选择(或放置在放置目标上)和一些属性的文件的引用。从 File API Section 7.2文件属性,我们可以阅读:,还有一个 size 属性: 同样,没有路径,只是只读文件名。 因此: $ ul b (elm_input || event.dataTransfer).files 给出FileList对象。 (elm_input || event.dataTransfer).files.length 给出文件的数量。 (elm_input || event.dataTransfer).files [0] 是第一个选中的文件。 (elm_input || event.dataTransfer).files [0] .name 是所选第一个文件的文件名(这是从输入type =file返回的值)。 这个'用于二进制数据的URL方案如文件,以便它们可以在Web应用程序中被引用'可以保存一个用户选择的文件的私人引用? 从 lockquote 本规范定义了一个具有以下排序URL的方案: blob:550e8400-e29b-41d4-a716-446655440000#aboutABBA。 这些存储在 URL存储中(浏览器甚至应该有自己的迷你HTTP服务器,所以可以在css,img src和甚至XMLHttpRequest。 $ b 可以用下面的方法创建这些 Blob URL s: var myBlobURL = window.URL.createFor(object); 返回一个 Blob URL 在它被自动撤销之后首先使用。 var myBlobURL = window.URL.createObjectURL(object,flag_oneTimeOnly); 返回一个可重用的 Blob URL (除非flag_oneTImeOnly的计算结果为true),并且可以通过 window.URL.revokeObjectURL(myBlobURL)来撤销。 宾果您可能认为...但是... URL商店仅在会话期间被维护(所以它将在页面刷新后仍然存在,因为它仍然是相同的会话),并在文档被卸载时丢失。 $ b使用对象网址: $ b $ b And indeed, the HTML 4.01 spec section 17.4.1 specifies that:Given the facts that javascript can both modify and submit a form (including a file-input) and one could use css to hide forms/form-elements (like the file-input), the above statements alone would make it possible to silently upload files from a user's computer without his intention/knowledge.It is clearly extremely important that this is not possible, and as such, (above) RFC1867 states in section 8 security Considerations:However, the only browser (I'm aware of) that ever implemented this features was (some older versions of) Opera: it accepted a <input type="file" value="C:\foo\bar.txt> or value set by javascript (elm_input_file.value='c:\\foo\\bar.txt';).When this file-box was unchanged upon form-submit, Opera would pop-up a security-window informing the user of what file(s) where about to be uploaded to what location (url/webserver).Now one might argue that all other browsers were in violation of the spec, but that would be wrong: since the spec stated: "may" (it did not say "must") ".. use value attribute as the initial file name".And, if the browser doesn't accept setting the file-input value (aka, having that value just be 'read-only') then the browser also would not need to pop-up such a 'scary' and 'difficult' security-pop-up (that might not even serve it's purpose if the user didn't understand it (and/or was 'conditioned' to always click 'OK')).Let's fast-forward to HTML 5 then..Here all this ambiguity is cleared up (yet it still takes some puzzling):Under 4.10.7.1.18 File Upload state we can read in the bookkeeping details:So, a file-input's value attribute must be omitted, yet it also operates in some kind of 'mode' called 'filename' which is described in 4.10.7.4 Common input element APIs:skipping to this 'mode filename':Let me repeat that: "it must throw an InvalidStateError exception" if one tries to set an file-input value to a string that is not empty !!! (But one can clear the input-field by setting it's value to an empty string.)Thus, currently and in the foreseeable HTML5 future (and in the past, except Opera), only the user can populate a file-input (via the browser or os-supplied 'file-chooser'). One can not (re-)populate the file-input to a file/directory with javascript or by setting the default value.Getting the filename/file-pathNow, suppose it was not impossible to (re-)populate a file-input with a default value, then obviously you'd need the full path: directory + filename(+ extension).In the past, some browsers like (most notable) IE6 (up to IE8) did reveal the full path+filename as value: just a simple alert( elm_input_file.value ); etc. in javascript AND the browser also sent this full path+filename(+ extension) to the receiving server on form-submit.That is a realistic security/privacy risk: a malicious website(owner/exploiter) could obtain the path to a users home-directory (where personal stuff, accounts, cookies, user-portion of registry, history, favorites, desktop etc. is located in known constant locations) when the typical non-tech windows-user will upload his files from: C:\Documents and Settings\[UserName]\My Documents\My Pictures\kinky_stuff\image.ext.I did not even talk about the risks while transmitting the data (even 'encrypted' via https) or 'safe' storage of this data!As such, more and more alternative browsers were starting to follow one of the oldest proven security-measures: share information on a need-to-know basis.And the vast majority of websites do not need to know the file-path, so they only revealed the filename(+ extension).By the time IE8 was released, MS decided to follow the competition and added an URLAction option, called "Include local directory path when uploading files", which was set to 'disabled' for the general internet-zone (and 'enabled' in the trusted zone) by default.This change created a small havoc (mostly in 'optimized for IE' environments) where all kinds of both custom code and proprietary 'controls' couldn't get the filename of files that were uploaded: they were hard-coded to expect a string containing a full path and extract the part after the last backslash (or forward slash if you were lucky...).Along came HTML5,and as you have read above, the 'mode filename' specifies: and they note that and function extractFilename(s){ // returns string containing everything from the end of the string // that is not a back/forward slash or an empty string on error // so one can check if return_value==='' return (typeof s==='string' && (s=s.match(/[^\\\/]+$/)) && s[0]) || '';}Let's recap (getting the path/file name):older browsers (and newer browsers where one could enable this as an option like IE>=8) will reveal a full windows/unix pathless older browsers will not reveal any path, just a filename(+extension)current/future/HTML5-compliant browsers will always pre-pend the string: c:\fakepath\ to the filename when getting the file-input's valueOn top of that, they will only return the first filename (from a 'list of selected files') should the file-input accept multiple files and the user has selected multiple files.Thus, in the recent past, currently and in the foreseeable HTML5 future one will usually only get the file-name.That brings us to the last thing we need to examine: this 'list of selected files' / multiple-files, that leads us to the third part of the puzzle:(HTML5) File APIFirst of all: the 'File API' should not be confused with the 'File System API', here is the abstract of the File System API: The 'sandboxed sections of a user's local filesystem' already clearly indicates that one can't use this to get a hold of user-files outside of the sandbox (so not relevant to the question, although one could copy the user-selected file to the persistent local storage and re-upload that copy using AJAX etc. Useful as a 'retry' on failed upload.. But it wouldn't be a pointer to the original file that might have changed in the mean-time).Even more important is the fact that only webkit (think older versions of chrome) implemented this feature and the spec is most probably not going to survive as it is no more actively maintained, the specification is abandonned for the moment as it didn't get any significant tractionLet's continue with the 'File API',it's abstract tells us:So, FileList can be populated by an input field in file-mode: <input type="file">.That means that all of the above about the value-attribute still applies!When an input field is in file-mode, it gets a read-only attribute files which is an array-like FileList object that references the input-element's user-selected file(s) and is(/are) accessible by the FileList interface.Did I mention that the files-attribute of the type FileList is read-only ? :Well, what about drag and drop?From the mdn-documentation - Selecting files using drag and dropSo, (just like the input-field type="file",) the event's dataTransfer attribute has an array-like attribute files which is an array-like FileList object and we have just learned (above) that the FileList is read-only..The FileList contains references to the file(s) that a user selected (or dropped on a drop-target) and some attributes. From the File API Section 7.2 File Attributes we can read:and there is a size attribute: Again, no path, just the read-only filename.Thus:(elm_input||event.dataTransfer).files gives the FileList Object.(elm_input||event.dataTransfer).files.length gives the number of files.(elm_input||event.dataTransfer).files[0] is the first file selected.(elm_input||event.dataTransfer).files[0].name is the file-name of the first file selected(and this is the value that is returned from an input type="file").What about this 'URL scheme for use with binary data such as files, so that they can be referenced within web applications', surely that can hold an private reference to a file that a user selected?From the File API - A URL for Blob and File reference we can learn that:These are stored in an URL store (and browsers should even have their own mini HTTP-server aboard so one can use these urls in css, img src and even XMLHttpRequest.One can create those Blob URLs with:var myBlobURL=window.URL.createFor(object); returns a Blob URL that is automatically revoked after it's first use.var myBlobURL=window.URL.createObjectURL(object, flag_oneTimeOnly); returns a re-usable Blob URL (unless the flag_oneTImeOnly evaluates to true) and can be revoked with window.URL.revokeObjectURL(myBlobURL).Bingo you might think... however... the URL Store is only maintained during a session (so it will survive a page-refresh, since it is still the same session) and lost when the document is unloaded.From the MDN - Using object URLs:That means, that even when you store the Blob URL string in a cookie or persistent local storage, that string would be useless in a new session!That should bring us to a full circle and the final conclusion:It is not possible to (re-)populate an input-field or user-selected file (that is not in the browsers sandboxed 'Local storage' area).(Unless you force your users to use an outdated version of Opera, or force your users to use IE and some activeX coding/modules (implementing a custom file-picker), etc)Some further reading:http://www.cs.tut.fi/~jkorpela/forms/file.htmlhttps://developer.mozilla.org/en-US/docs/Using_files_from_web_applicationshttp://www.html5rocks.com/en/tutorials/file/filesystem/http://www.html5rocks.com/en/tutorials/file/dndfiles/http://caniuse.com/filereaderJavaScript: The Definitive Guide - David Flanagan, chapter-22: The filesystem apiHow to save the window.URL.createObjectURL() result for future use?How long does a Blob persist?How to resolve the C:\fakepath? 这篇关于记住并重新填充文件输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!