it-swarm-es.com

Cómo obtener la ruta del archivo desde el formulario de entrada HTML en Firefox 3

Tenemos un formulario HTML simple con <input type="file">, como se muestra a continuación:

<form>
  <label for="attachment">Attachment:</label>
  <input type="file" name="attachment" id="attachment">
  <input type="submit">
</form>

En IE7 (y probablemente en todos los navegadores famosos, incluido el antiguo Firefox 2), si enviamos un archivo como '// server1/path/to/file/filename' funciona correctamente y proporciona la ruta completa al archivo y al nombre del archivo.

En Firefox 3, solo devuelve 'nombre de archivo', debido a su nueva 'característica de seguridad' para truncar la ruta, como se explica en el sistema de seguimiento de errores de Firefox ( https://bugzilla.mozilla.org/show_bug.cgi?id= 143220 )

No tengo ni idea de cómo superar esta "nueva característica" porque hace que todos los formularios de carga en mi aplicación web dejen de funcionar en Firefox 3.

¿Alguien puede ayudar a encontrar una solución única para obtener la ruta del archivo tanto en Firefox 3 como en IE7?

51
m_pGladiator

En IE7 (y probablemente en todos los navegadores famosos, incluido el antiguo Firefox 2), si enviamos un archivo como '// server1/path/to/file/filename' funciona correctamente y proporciona la ruta completa al archivo y al nombre del archivo.

No tengo ni idea de cómo superar esta "nueva característica" porque hace que todos los formularios de carga en mi aplicación web dejen de funcionar en Firefox 3.

Hay un gran malentendido aquí. ¿Por qué alguna vez necesita la ruta completa del archivo en el lado del servidor? Imagina que soy el cliente y tengo un archivo en C:\path\to\passwords.txt y te doy la ruta completa del archivo. ¿Cómo podría usted, como servidor, obtener su contenido? ¿Tiene una conexión abierta TCP a mi sistema de archivos de disco local? ¿Probó la funcionalidad de carga de archivos cuando puso su aplicación web en producción en una máquina servidor diferente?

Solo funcionará cuando ambos el cliente y el servidor se ejecuten en físicamente el mismo máquina, porque entonces tendrá acceso al igual sistema de archivos del disco duro. Esto solo ocurrirá cuando esté desarrollando localmente su sitio web y, por lo tanto, el navegador web (cliente) y el servidor web (servidor) por coincidencia se ejecutan en la misma máquina.

El hecho de que la ruta completa del archivo se envíe en MSIE y otros navegadores web antiguos se debe a un error de seguridad. Las especificaciones W3 y RFC2388 nunca han mencionado que se incluya la ruta completa del archivo. Sólo el nombre del archivo. Firefox está haciendo su trabajo correctamente.

Para manejar los archivos cargados, no necesita conocer la ruta completa del archivo. En su lugar, debería estar interesado en el archivo completo contenidos que el cliente ya ha enviado al servidor en el cuerpo de la solicitud en caso de una solicitud multipart/form-data. Cambie su formulario para que se parezca a lo siguiente como se indica en RFC2388:

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

La forma de obtener el contenido del archivo cargado en el lado del servidor depende del lenguaje de programación del lado del servidor que esté utilizando.

  • Java/JSP : le gustaría usar HttpServletRequest#getPart() o Apache Commons FileUpload API para analizarlo. Debería terminar con una InputStream con el contenido del archivo que a su vez puede escribir en cualquier OutputStream a su gusto. Puedes encontrar un ejemplo en esta respuesta .

  • Java/JSF : le gustaría usar el componente <h:inputFile> o cualquier otro componente de carga de archivos proporcionado por la biblioteca de componentes que está usando. También aquí, le gustaría obtener el contenido del archivo en forma de una InputStream. Ver esta respuesta para un ejemplo.

  • PHP: el contenido del archivo ya está almacenado implícitamente en el disco temporal. Le gustaría usar la función move_uploaded_file() para moverla a la ubicación deseada. Vea también PHP manual .

  • ASP.NET : no hay una respuesta detallada de mi parte porque no lo hago, pero Google ha encontrado algunos ejemplos para mí: ASP.NET ejemplo , ASP.NET 2.0 ejemplo

Cuando quiera obtener la parte del nombre del archivo cargado, debe trim la ruta completa fuera del nombre del archivo. Esta información es completamente irrelevante para usted. Vea también, por ejemplo, esta Apache Commons FileUpload FAQ entry

¿Por qué FileItem.getName () devuelve la ruta completa, y no solo el nombre del archivo?

Internet Explorer proporciona la ruta completa al archivo cargado y no solo el nombre del archivo base. Dado que FileUpload proporciona exactamente lo que le proporcionó el cliente (navegador), es posible que desee eliminar esta información de ruta en su aplicación.

60
BalusC

Para que la vista previa en Firefox funcione, este adjunto es objeto de elemento adjunto en el primer ejemplo:

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

En realidad, justo antes de que saliera FF3, hice algunos experimentos, y FF2 solo envía el nombre de archivo, como lo hizo Opera 9.0. Solo IE envía la ruta completa. El comportamiento tiene sentido, ya que el servidor no tiene que saber dónde almacena el archivo el usuario en su computadora, es irrelevante para el proceso de carga. ¡A menos que esté escribiendo una aplicación de intranet y obtenga el archivo mediante acceso directo a la red!

Lo que ha cambiado (y ese es el punto real del elemento de error al que apunta) es que FF3 ya no permite el acceso a la ruta del archivo desde JavaScript. Y no permitiré escribir/pegar una ruta allí, lo que es más molesto para mí: tengo una extensión de Shell que copia la ruta de un archivo desde el Explorador de Windows al portapapeles y la usé mucho de esa forma. Resolví el problema usando la extensión DragDropUpload. Pero esto se vuelve fuera de tema, me temo.

Me pregunto qué están haciendo sus formularios web para dejar de trabajar con este nuevo comportamiento.

[EDITAR] Después de leer la página enlazada por Mike, veo los usos de la ruta en la intranet (por ejemplo, identificar a un usuario) y los usos locales (vista previa de una imagen, administración local de archivos). El usuario Jam-es parece proporcionar una solución alternativa con nsIDOMFile (aún no probado).

2
PhiLho

No podemos obtener la ruta completa del archivo en FF3. Lo siguiente puede ser útil para la personalización de componentes de archivos.

<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
Jay

Esta es una solución/solución alternativa ... En FF3, puede recuperar la ruta completa del archivo en un cuadro de texto en lugar del cuadro de búsqueda de archivos. Y eso también ... ¡Al arrastrar/soltar el archivo!

Puede arrastrar y soltar su archivo en un cuadro de texto en su página html. y mostrará la ruta completa del archivo. Estos datos pueden transferirse a su servidor fácilmente o manipularlos.

Todo lo que tienes que hacer es usar la extensión DragDropUpload

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

Esta extensión lo ayudará a arrastrar y soltar archivos en el cuadro de búsqueda de archivos (archivo de entrada). Pero todavía no puede obtener la ruta completa del archivo, si intenta recuperar.

Así que, pellizqué un poco esta extensión. De la forma en que puedo arrastrar, soltar un archivo en cualquier cuadro de "Entrada de texto" y obtener la ruta completa del archivo. Y así puedo obtener la ruta completa del archivo en FF3 Firefox 3.

0
Kumaresan

Simplemente no puedes hacerlo con FF3.

La otra opción podría ser usar un applet u otros controles para seleccionar y cargar archivos.

0
roh

Una forma extremadamente fea de resolver esto es hacer que el usuario escriba manualmente el directorio en un cuadro de texto y lo agregue de nuevo al frente del valor del archivo en el JavaScript.

Desordenado ... pero depende del nivel de usuario con el que está trabajando y soluciona el problema de seguridad.

<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
dan

Eche un vistazo a XPCOM , puede haber algo que pueda usar si Firefox 3 es utilizado por un cliente.

0
LohanJ

Este es un ejemplo que podría funcionar para usted si lo que necesita no es exactamente la ruta, sino una referencia al archivo que trabaja fuera de línea.

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

Está en francés, pero el código es javascript :)

Estas son las referencias a las que apunta el artículo: http://developer.mozilla.org/en/nsIDOMFilehttp://developer.mozilla.org/en/nsIDOMFileList

0
Victor