Как получить путь к файлу из формы ввода HTML в Firefox 3 - PullRequest
51 голосов
/ 17 сентября 2008

У нас есть простая 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?

Ответы [ 9 ]

60 голосов
/ 30 июля 2010

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

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

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

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

То, что полный путь к файлу отправляется в 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 запись

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

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

10 голосов
/ 03 января 2010

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

           if (attachment.files)
             previewImage.src = attachment.files.item(0).getAsDataURL();
           else
             previewImage.src = attachment.value;
2 голосов
/ 08 декабря 2010

Мы не можем получить полный путь к файлу в 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>
2 голосов
/ 08 октября 2008

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

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

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

[РЕДАКТИРОВАТЬ] После прочтения страницы, на которую ссылается Майк, я действительно вижу использование пути в интрасети (например, идентификация пользователя) и локальное использование (предварительный просмотр изображения, локальное управление файлами). Пользователь Jam-es, кажется, предлагает обходной путь с помощью nsIDOMFile (еще не пробовал).

0 голосов
/ 21 августа 2009

Один очень уродливый способ решить эту проблему - попросить пользователя вручную ввести каталог в текстовое поле и добавить его обратно в начало значения файла в 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;
0 голосов
/ 23 июля 2009

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

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

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

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

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

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

0 голосов
/ 17 сентября 2008

Это пример, который может вам пригодиться, если вам нужен не только путь, а ссылка на файл, работающий в автономном режиме.

http://www.ab -d.fr / дата / 2008-07-12 /

Это на французском, но код javascript:)

Это ссылки, на которые указывает статья: http://developer.mozilla.org/en/nsIDOMFile http://developer.mozilla.org/en/nsIDOMFileList

0 голосов
/ 17 сентября 2008

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

0 голосов
/ 17 сентября 2008

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

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

...