Attachment:

如何从Firefox 3中的HTML输入表单获取文件路径

如何从Firefox 3中的HTML输入表单获取文件路径

How to get the file path from HTML input form in Firefox 3

我们有一个带有的简单HTML表单,如下所示:

1
2
3
4
5
<form>
  <label for="attachment">Attachment:</label>
  <input type="file" name="attachment" id="attachment">
  <input type="submit">
</form>

在IE7(可能是所有著名的浏览器,包括旧的Firefox 2)中,如果我们提交" // server1 / path / to / file / filename"之类的文件,它将正常工作并提供指向该文件的完整路径。
文件和文件名。

在Firefox 3中,由于其新的"安全功能"来截断路径,因此它仅返回"文件名",如Firefox Bug跟踪系统(https://bugzilla.mozilla.org/show_bug.cgi?id=143220)所述

我不知道如何克服这个"新功能",因为它会使我的Web应用程序中的所有上传表单停止在Firefox 3上运行。

谁能帮忙找到一个解决方案来在Firefox 3和IE7上获取文件路径?


In IE7 (and probably all famous browsers, including old Firefox 2), if we submit a file like '//server1/path/to/file/filename' it works properly and gives the full path to the file and the filename.

I have no clue how to overcome this 'new feature' because it causes all upload forms in my webapp to stop working on Firefox 3.

这里有一个重大误会。为什么在服务器端需要完整的文件路径?假设我是客户端,并且在C:\path\to\passwords.txt处有一个文件,并且将完整的文件路径提供给您。作为服务器,您将如何获取其内容?您是否有到本地磁盘文件系统的开放式TCP连接?将Web应用程序在其他服务器上投入生产后,是否测试了文件上传功能?

只有当客户端和服务器都在同一台计算机上运行时,它才起作用,因为您将可以访问同一硬盘文件系统。仅当您在本地开发网站时,Webbrowser(客户端)和Webserver(服务器)同时运行在同一台计算机上时,才会发生这种情况。

完整文件路径正在MSIE和其他古老的网络浏览器中发送是由于安全漏洞。 W3和RFC2388规范从未提及包含完整文件路径。仅文件名。 Firefox可以正常工作。

要处理上传的文件,您不需要知道完整的文件路径。如果是multipart/form-data请求,您应该对客户端已在请求正文中发送给服务器的完整文件内容感兴趣。更改表单,使其外观类似于RFC2388中所述:

1
2
3
4
<form action="upload-script-url" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit">
</form>

如何在服务器端获取上载文件的内容取决于您使用的服务器端编程语言。

  • Java / JSP:您想使用HttpServletRequest#getPart()或Apache Commons FileUpload API对其进行解析。您应该以InputStream结尾,该文件的内容可以随您的喜好写入任何OutputStream中。您可以在此答案中找到一个示例。

  • Java / JSF:您想使用组件或所使用的组件库提供的任何其他文件上载组件。同样在这里,您想要获得InputStream风格的文件内容。有关示例,请参见此答案。

  • PHP:文件内容已隐式存储在临时磁盘上。您想使用move_uploaded_file()函数将其移动到所需位置。另请参见PHP手册。

  • ASP.NET:我没有提供详细的答案,因为我没有这样做,但是Google为我找到了一些示例:ASP.NET示例,ASP.NET 2.0示例

每当要获取上载文件的文件名部分时,都应从文件名中修剪完整路径。该信息即与您完全无关。另请参见例如此Apache Commons FileUpload FAQ条目

Why does FileItem.getName() return the whole path, and not just the file name?

Internet Explorer provides the entire path to the uploaded file and not just the base file name. Since FileUpload provides exactly what was supplied by the client (browser), you may want to remove this path information in your application.


为了在Firefox中进行预览,可以使用此功能-附件是第一个示例中的附件元素的对象:

1
2
3
4
           if (attachment.files)
             previewImage.src = attachment.files.item(0).getAsDataURL();
           else
             previewImage.src = attachment.value;


我们无法在FF3中获得完整的文件路径。以下内容可能对自定义文件组件很有用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
function setFileName()
{
    var file1=document.forms[0].firstAttachmentFileName.value;

    initFileUploads('firstFile1','fileinputs1',file1);
    }
function initFileUploads(fileName,fileinputs,fileValue) {
    var fakeFileUpload = document.createElement('div');
    fakeFileUpload.className = 'fakefile';
    var filename = document.createElement('input');
    filename.type='text';
    filename.value=fileValue;
    filename.id=fileName;
    filename.title='Title';
    fakeFileUpload.appendChild(filename);
    var image = document.createElement('input');
    image.type='button';
    image.value='Browse File';
    image.size=5100;
    image.style.border=0;
    fakeFileUpload.appendChild(image);
    var x = document.getElementsByTagName('input');
    for (var i=0; i<x.length;i++) {
        if (x[i].type != 'file') continue;
        if (x[i].parentNode.className != fileinputs) continue;
        x[i].className = 'file hidden';
        var clone = fakeFileUpload.cloneNode(true);
        x[i].parentNode.appendChild(clone);
        x[i].relatedElement = clone.getElementsByTagName('input')[0];
        x[i].onchange= function () {
            this.relatedElement.value = this.value;
        }}
    if(document.forms[0].firstFile != null && document.getElementById('firstFile1') != null)
    {
    document.getElementById('firstFile1').value= document.forms[0].firstFile.value;
    document.forms[0].firstAttachmentFileName.title=document.forms[0].firstFile.value;
    }
}

function submitFile()
{
alert( document.forms[0].firstAttachmentFileName.value);
}

<style>div.fileinputs1 {position: relative;}div.fileinputs2 {position: relative;}
div.fakefile {position: absolute;top: 0px;left: 0px;z-index: 1;}
input.file {position: relative;text-align: right;-moz-opacity:0 ;filter:alpha(opacity: 0);
    opacity: 0;z-index: 2;}</style>

<html>
<body onLoad ="setFileName();">
<form>

<INPUT TYPE=file NAME="firstAttachmentFileName" styleClass="file" />

<INPUT type="button" value="submit" onclick="submitFile();" />
</form>
</body>
</html>

实际上,就在FF3推出之前,我做了一些实验,FF2仅发送文件名,就像Opera 9.0一样。仅IE发送完整路径。这种行为是有道理的,因为服务器不必知道用户将文件存储在计算机上的位置,因此与上传过程无关。除非您正在编写Intranet应用程序并通过直接网络访问来获取文件!

发生了什么变化(这就是您所指的错误项的真正意义)是FF3不再允许从JavaScript访问文件路径。而且不要在其中键入/粘贴路径,这对我来说比较烦人:我有一个shell扩展,它将文件的路径从Windows资源管理器复制到剪贴板,并且我经常以这种形式使用它。我通过使用DragDropUpload扩展解决了该问题。恐怕这变成了题外话。

我想知道您的Web窗体正在做什么以停止使用这种新行为。

[编辑]在阅读由Mike链接的页面后,我确实看到该路径的Intranet使用(例如,标识用户)和本地使用(显示图像的预览,文件的本地管理)。用户Jam-es似乎为nsIDOMFile提供了一种解决方法(尚未尝试)。


解决此问题的一种极为丑陋的方法是让用户手动在文本框中键入目录,然后将其重新添加到JavaScript中文件值的前面。

混乱...但这取决于您正在使用的用户级别,并且可以解决安全问题。

1
2
3
4
5
<form>
    <input type="text" id="file_path" value="C:/" />
    <input type="file" id="file_name" />
    <input type="button" onclick="ajax_restore();" value="Restore Database" />
</form>

的JavaScript

1
2
var str = document.getElementById('file_path').value;
var str = str + document.getElementById('file_name').value;

这是一个替代解决方案/修复程序...在FF3中,您可以在文本框中而不是文件浏览框中检索文件的完整路径。还有...通过拖放文件!

您可以将文件拖放到html页面的文本框中。它将显示文件的完整路径。这些数据可以轻松地传输到您的服务器或对其进行操作。

您所要做的就是使用扩展DragDropUpload

http://www.teslacore.it/wiki/index.php?title=DragDropUpload

此扩展名将帮助您将文件拖放到"文件浏览(输入文件)"框中。但是,如果您尝试检索,则仍然无法获取文件的完整路径。

因此,我对该扩展进行了一些微调。通过这种方式,我可以将文件拖放到任何"文本输入"框中,并获得文件的完整路径。因此,我可以在FF3 Firefox 3中获取文件的完整路径。


如果您需要的不是确切的路径,而是对脱机工作文件的引用,那么这是一个对您有用的示例。

http://www.ab-d.fr/date/2008-07-12/

它是法语,但是代码是javascript :)

这是本文指向的参考:
http://developer.mozilla.org/en/nsIDOMFile
http://developer.mozilla.org/en/nsIDOMFileList


看一下XPCOM,如果客户端使用Firefox 3,则可能会使用某些东西。


根本无法使用FF3做到这一点。

另一个选项可能是使用applet或其他控件来选择和上传文件。


推荐阅读