web-dev-qa-db-fra.com

Comment obtenir le chemin du fichier depuis le formulaire de saisie HTML dans Firefox 3

Nous avons un formulaire HTML simple avec <input type="file">, comme ci-dessous:

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

Dans IE7 (et probablement tous les navigateurs célèbres, y compris l'ancien Firefox 2), si nous soumettons un fichier tel que '// server1/path/to/file/filename', il fonctionnera correctement et donnera le chemin d'accès complet au fichier et au nom du fichier.

Dans Firefox 3, il ne renvoie que "nom de fichier", en raison de sa nouvelle "fonctionnalité de sécurité" permettant de tronquer le chemin, comme expliqué dans le système de suivi des bogues de Firefox ( https://bugzilla.mozilla.org/show_bug.cgi?). id = 14322 )

Je ne sais pas comment surmonter cette "nouvelle fonctionnalité", car tous les formulaires de téléchargement de mon application Web ne fonctionnent plus sous Firefox 3.

Quelqu'un peut-il aider à trouver une solution unique pour obtenir le chemin du fichier à la fois sur Firefox 3 et IE7?

52
m_pGladiator

Dans IE7 (et probablement tous les navigateurs célèbres, y compris l'ancien Firefox 2), si nous soumettons un fichier tel que '// server1/path/to/file/filename', il fonctionnera correctement et donnera le chemin d'accès complet au fichier et au nom du fichier.

Je ne sais pas comment surmonter cette "nouvelle fonctionnalité", car tous les formulaires de téléchargement de mon application Web ne fonctionnent plus sous Firefox 3.

Il y a un malentendu majeur ici. Pourquoi avez-vous besoin du chemin du fichier complet du côté du serveur? Imaginez que je suis le client et que j'ai un fichier à C:\path\to\passwords.txt Et que je vous donne le chemin complet du fichier. Comment voulez-vous, en tant que serveur, obtenir son contenu? Avez-vous une connexion ouverte TCP à mon système de fichiers sur disque local? Avez-vous testé la fonctionnalité de téléchargement de fichier lorsque vous avez mis votre application Web en production sur un autre serveur?

Cela ne fonctionnera que lorsque les deux le client et le serveur s'exécutent à physiquement la même machine , car vous aurez alors le accès au même système de fichiers du disque dur. Cela ne se produirait que lorsque vous développez votre site Web localement et que, par conséquent, le navigateur Web (client) et le serveur Web (serveur) s'exécutent sur le même ordinateur.

Le chemin complet du fichier est envoyé dans MSIE et d’autres anciens navigateurs Web, ce qui est dû à un bogue de sécurité. Les spécifications W et RFC2388 n'ont jamais indiqué d'inclure le chemin d'accès complet au fichier. Seul le nom du fichier. Firefox fait son travail correctement.

Pour gérer les fichiers téléchargés, vous n'avez pas besoin de connaître le chemin d'accès complet au fichier. Vous devriez plutôt vous intéresser au contenu complet du fichier que le client a déjà envoyé au serveur dans le corps de la requête dans le cas d'un multipart/form-data demande. Modifiez votre formulaire pour qu'il ressemble à ce qui suit, comme indiqué dans la RFC2388:

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

Comment obtenir le contenu du fichier téléchargé côté serveur dépend du langage de programmation côté serveur que vous utilisez.

  • Java/JSP : vous souhaitez utiliser HttpServletRequest#getPart() ou Apache Commons FileUpload API pour l'analyser. Vous devriez vous retrouver avec un InputStream avec le contenu du fichier que vous pouvez à son tour écrire dans n'importe quel OutputStream à votre goût. Vous pouvez trouver un exemple dans cette réponse .

  • Java/JSF : vous souhaitez utiliser le composant <h:inputFile> ou tout autre composant de téléchargement de fichier fourni par la bibliothèque de composants que vous utilisez. Ici aussi, vous voudriez obtenir le contenu du fichier à la manière d'un InputStream. Voir cette réponse pour un exemple.

  • [~ # ~] php [~ # ~] : le contenu du fichier est déjà implicitement stocké sur le disque temporaire. Vous souhaitez utiliser la fonction move_uploaded_file() pour la déplacer à l'emplacement souhaité. Voir aussi manuel PHP .

  • ASP.NET : aucune réponse détaillée de ma part car je ne le fais pas, mais Google a trouvé quelques exemples pour moi: ASP. Exemple NET , exemple ASP.NET 2.

Chaque fois que vous souhaitez obtenir la partie du nom de fichier du nom du fichier téléchargé, vous devez rogner le chemin complet du nom de fichier. Cette information est à savoir totalement hors de propos pour vous. Voir aussi par exemple this Apache Commons FileUpload FAQ entrée

Pourquoi FileItem.getName () renvoie-t-il l'intégralité du chemin, et pas uniquement le nom du fichier?

Internet Explorer fournit le chemin d'accès complet au fichier téléchargé et pas seulement le nom du fichier de base. Étant donné que FileUpload fournit exactement ce qui a été fourni par le client (navigateur), vous souhaiterez peut-être supprimer ces informations de chemin dans votre application.

60
BalusC

Pour que l’aperçu dans Firefox fonctionne, la pièce jointe est l’objet de l’attachement élément dans le premier exemple:

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

En fait, juste avant la sortie de FF3, j’ai fait quelques expériences et FF2 n’envoie que le nom de fichier, comme le fait Opera 9.0. Only IE envoie le chemin complet. Le comportement a du sens, car le serveur n'a pas besoin de savoir où l'utilisateur stocke le fichier sur son ordinateur, cela n'a aucune importance pour le processus de téléchargement. Sauf si vous écrivez une application intranet et récupérez le fichier par accès direct au réseau!

Ce qui a changé (et c’est là que réside l’élément de bogue que vous avez signalé) est que FF3 ne permet plus d’accéder au chemin du fichier à partir de JavaScript. Et je ne laisserai pas taper/coller un chemin là-bas, ce qui est plus gênant pour moi: j’ai une extension Shell qui copie le chemin d’un fichier de l’explorateur Windows dans le presse-papier et je l’ai beaucoup utilisé sous cette forme. J'ai résolu le problème en utilisant l'extension DragDropUpload. Mais je crains que cela ne soit plus un sujet.

Je me demande ce que vos formulaires Web font pour cesser de fonctionner avec ce nouveau comportement.

[EDIT] Après avoir lu la page liée par Mike, je vois bien les utilisations intranet du chemin (identifier un utilisateur par exemple) et les utilisations locales (afficher l'aperçu d'une image, gestion locale des fichiers). User Jam-es semble fournir une solution de contournement avec nsIDOMFile (pas encore essayé).

2
PhiLho

Nous ne pouvons pas obtenir le chemin complet du fichier dans FF3. Ce qui suit peut être utile pour la personnalisation du composant de fichier.

<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

C’est une solution/solution de rechange ... Dans FF3, vous pouvez récupérer le chemin complet du fichier dans une zone de texte au lieu d’une zone de navigation de fichier. Et cela aussi ... En glissant/déposant le fichier!

Vous pouvez faire glisser votre fichier dans une zone de texte de votre page HTML. et il affichera le chemin complet du fichier. Ces données peuvent facilement être transférées sur votre serveur ou manipulées.

Tout ce que vous avez à faire est d'utiliser l'extension DragDropUpload

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

Cette extension vous aidera à faire glisser des fichiers dans votre boîte de dialogue Parcourir (fichier d'entrée). Mais vous ne pourrez toujours pas obtenir le chemin d'accès complet au fichier, si vous essayez de le récupérer.

Alors, j'ai légèrement modifié cette extension. De la même manière, je peux faire glisser un fichier sur n'importe quelle boîte "Entrée de texte" et obtenir le chemin complet du fichier. Et ainsi je peux pouvoir obtenir le chemin complet du fichier dans FF3 Firefox 3.

0
Kumaresan

Vous ne pouvez tout simplement pas le faire avec FF3.

L’autre option pourrait être l’applet ou d’autres contrôles pour sélectionner et télécharger des fichiers.

0
roh

Une façon extrêmement laide de résoudre ce problème consiste à demander à l'utilisateur de taper manuellement le répertoire dans une zone de texte, puis de l'ajouter à nouveau au début de la valeur du fichier dans JavaScript.

En désordre ... mais cela dépend du niveau d’utilisateur avec lequel vous travaillez et résout le problème de sécurité.

<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

Jetez un œil à XPCOM , il y a peut-être quelque chose que vous pouvez utiliser si Firefox 3 est utilisé par un client.

0
LohanJ

Ceci est un exemple qui pourrait fonctionner pour vous si ce dont vous avez besoin n'est pas exactement le chemin, mais une référence au fichier fonctionnant hors ligne.

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

C'est en français, mais le code est javascript :)

Voici les références auxquelles l'article renvoie: http://developer.mozilla.org/en/nsIDOMFilehttp://developer.mozilla.org/en/nsIDOMFileList

0
Victor