Как получить путь к файлу из формы ввода HTML в Firefox 3

У нас есть простая форма HTML с <input type="file">, как показано ниже:

<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 (https://bugzilla.mozilla.org/show_bug.cgi?id=143220)

У меня нет подсказки, как преодолеть эту "новую функцию", потому что она заставляет все формы загрузки в моем веб-браузере перестать работать с Firefox 3.

Может ли кто-нибудь помочь найти одно решение для получения пути к файлу как в Firefox 3, так и в IE7?

Ответы

Ответ 1

В IE7 (и, вероятно, во всех известных браузерах, включая старый Firefox 2), если мы отправляем файл, например '//server1/path/to/file/filename', он работает правильно и дает полный путь к файлу, а имя файла.

У меня нет подсказки, как преодолеть эту "новую функцию", потому что она заставляет все формы загрузки в моем веб-браузере перестать работать с Firefox 3.

Здесь большое недоразумение. Зачем вам нужен полный путь к файлу на стороне сервера? Представьте, что я клиент, и у меня есть файл в C:\path\to\passwords.txt, и я даю вам полный путь к файлу. Как бы вы, как сервер, когда-либо получали его содержимое? У вас есть открытое TCP-соединение с моей локальной файловой системой на диске? Проверили ли вы функцию загрузки файлов, когда вы привели ваш webapp в производство на другой серверной машине?

Он будет работать только тогда, когда и клиент, и сервер будут работать на физически одной и той же машине, потому что у вас будет доступ к той же файловой системе на жестком диске. Это произойдет только в том случае, если вы локально разрабатываете свой веб-сайт, и поэтому веб-браузер (клиент) и веб-сервер (сервер) по совпадению запускаются на одном компьютере.

Что полный путь к файлу отправляется в MSIE и других древних веб-браузерах из-за ошибки безопасности. Параметры W3 и RFC2388 имеют никогда не упоминался, чтобы включить полный путь к файлу. Только имя файла. Firefox корректно выполняет свою работу.

Чтобы обрабатывать загруженные файлы, вам не нужно знать полный путь к файлу. Вам лучше всего заинтересовать полный файл содержимое, которое клиент уже отправил на сервер в тело запроса в случае запроса multipart/form-data. Измените форму, чтобы она выглядела следующим образом, как указано в RFC2388:

<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: вы хотите использовать компонент <h:inputFile> или любой другой компонент загрузки файлов, предоставляемый библиотекой компонентов, которую вы используете. Также здесь вы хотите получить содержимое файла в стиле InputStream. См. этот ответ для примера.

  • PHP: содержимое файла уже неявно хранится на временном диске. Вы хотите использовать функцию move_uploaded_file(), чтобы переместить ее в нужное место. См. Также Руководство по PHP.

  • ASP.NET: нет подробного ответа от меня, так как я этого не делаю, но Google нашел несколько примеров для меня: Пример ASP.NET, Пример ASP.NET 2.0

Всякий раз, когда вы хотите получить часть имени файла загруженного файла, вы должны обрезать полный путь от имени файла. Эта информация совершенно неактуальна для вас. Также см., Например, Apache Commons FileUpload FAQ entry

Почему FileItem.getName() возвращает весь путь, а не только имя файла?

Internet Explorer предоставляет весь путь к загруженному файлу, а не только имя базового файла. Поскольку FileUpload предоставляет именно то, что было предоставлено клиентом (браузером), вы можете удалить эту информацию о пути в своем приложении.

Ответ 2

Для предварительного просмотра в Firefox работает это - вложение - это объект элемента привязки в первом примере:

           if (attachment.files)
             previewImage.src = attachment.files.item(0).getAsDataURL();
           else
             previewImage.src = attachment.value;

Ответ 3

На самом деле, незадолго до выхода FF3 я сделал несколько экспериментов, и FF2 отправляет только имя файла, как и Opera 9.0. Только IE отправляет полный путь. Поведение имеет смысл, потому что сервер не должен знать, где пользователь хранит файл на своем компьютере, это не имеет отношения к процессу загрузки. Если вы не пишете приложение интрасети и не получаете файл по прямому сетевому доступу!

Что изменилось (и что реальная точка элемента ошибки вы указываете) заключается в том, что FF3 больше не разрешает доступ к файловому пути из JavaScript. И не позволяйте type/paste пути туда, что более раздражает для меня: у меня есть расширение оболочки, которое копирует путь файла из Windows Explorer в буфер обмена, и я использовал его много в такой форме. Я решил проблему, используя расширение DragDropUpload. Но я боюсь, что это будет не по теме.

Интересно, что делают ваши веб-формы, чтобы перестать работать с этим новым поведением.

[EDIT] После прочтения страницы, связанной с Майком, я вижу, действительно, использует путь к интрасети (например, для идентификации пользователя) и локального использования (покажите предварительный просмотр изображения, локальное управление файлами). Пользователь Jam-es, кажется, обеспечивает обходной путь с помощью nsIDOMFile (еще не пробовал).

Ответ 4

Мы не можем получить полный путь к файлу в FF3. Нижеследующее может быть полезно для настройки компонентов файла.

<script>

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&lt;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);
}
</script>
<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>
<div class="fileinputs1">
<INPUT TYPE=file NAME="firstAttachmentFileName" styleClass="file" />
</div>
<INPUT type="button" value="submit" onclick="submitFile();" />
</form>
</body>
</html>

Ответ 5

Один крайне уродливый способ разрешить это: вручную введите каталог в текстовое поле и добавьте его обратно к значению файла в JavaScript.

Беспокойство... но это зависит от уровня пользователя, с которым вы работаете, и обойти проблему безопасности.

<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

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

Ответ 6

Просто вы не можете сделать это с помощью FF3.

Другим вариантом может быть использование апплета или других элементов управления для выбора и загрузки файлов.

Ответ 7

Посмотрите XPCOM, может быть что-то, что вы можете использовать, если Firefox 3 используется клиентом.

Ответ 9

Это альтернативное решение /fix... В FF3 вы можете получить полный путь к файлу в текстовом поле вместо окна просмотра файлов. И это тоже... Перетащив файл!

Вы можете перетащить свой файл в текстовое поле на странице html. и он отобразит полный путь к файлу. Эти данные могут легко передаваться на ваш сервер или манипулировать ими.

Все, что вам нужно сделать, это использовать расширение DragDropUpload

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

Это расширение поможет вам перетащить файлы в окно просмотра файлов (входной файл). Но все равно вы не сможете получить полный путь к файлу, если вы попытаетесь получить.

Итак, я немного изменил это расширение. В способе, которым я могу перетащить файл на любой "текстовый вход" и получить полный путь к файлу. И таким образом я могу получить полный путь к файлу в FF3 Firefox 3.