SELFHTML

Stefan Falz:
Transmission de fichier par ASP

Page d'information: vue d'ensemble

vers le bas Stefan Falz
vers le bas Conditions préalables
vers le bas Le sujet
vers le bas Sécurité
vers le bas Exemple d'application
vers le bas Essayez vous-même

vers le bas 

Stefan Falz

Adresse électronique: Adresse électronique i-service@falz.de
Présence Internet: Page en langue allemande http://www.asp-solutions.de

Il s'agit ici d'un article traduit de l'allemand par la rédaction de SELFHTML actuel. Veuillez poser vos questions relatives à cet article uniquement à son auteur, prenant compte que celui-ci ne maîtrise peut-être pas la langue française!

vers le hautvers le bas 

Conditions préalables

Avant que vous ne commenciez à lire cet article, je voudrais tout de suite vous prévenir que quelques travaux préliminaires sont nécessaires pour pouvoir exécuter l'exemple sur votre serveur local Web ou sur un serveur Internet. Le système d'exploitation nécessaire doit être Windows 95, Windows 98 ou Windows NT à partir de la version 4.0. De plus, il faut que soit installé un serveur WEB soutenant ASP, comme par exemple: PersonalWebServer 4.0 ou InternetInformationServer à partir de la version 3.0 et qu'un module ASP à partir de la version 4.02.0685 soit installé. Les versions antérieures des composantes citées ne soutiennent chacune qu'une partie des routines nécessaires.

vers le hautvers le bas 

Le sujet

L'un des thèmes les plus évités du monde moderne de l'Internet est la transmission directe de fichiers par le biais du navigateur. Bien que tout le monde puisse établir un formulaire de saisie avec un champ de saisie pour fichiers (voir Page d'information: connexion exigée champs pour fichier à transmettre), on n'en rencontre qu'exceptionnellement. Cela est dû au fait d'une part: que les programmes qui assurent côté serveur la lecture du fichier dans le flux HTTP transmis et la sauvegarde finale sur le serveur sont excessivement chers; et d'autre part: au fait que l'internaute aura besoin de droits en écriture sur le répertoire du serveur Web, étant donné que sous ASP, de telles actions sont exécutées avec le compte standard IUSR_nomduserveur. Mais cependant, ces programmes ont lieu d'être, étant donné que pour l'instant, ASP n'est toujours pas en mesure de sauvegarder des fichiers binaires comme des images ou des programmes. Un tel module qui propose plus de confort, comme par exemple la prise en charge automatique des données envoyées et des noms de fichiers dans une banque de données, l'affectation automatique à des éléments déterminés etc., peut être trouvé à Page en langue allemande http://www.asp-solutions.de.

Fichier envoyer.html

<html>
<head>
<title>Transmettre un fichier par ASP</title>
</head>

<body>

<form method="POST" action="reception.asp" enctype="multipart/form-data" target="_new">
        <input type="file" name="File" size="50"><br>
        <input type="submit" value="TRANSMETTRE LE FICHIER" name="Submit">
</form>
</body>
</html>

Explication:

Pour le transfert de fichier, contrairement à un formulaire "normal" dans lequel la mention enctype="..." peut être omise, cette mention doit avoir la valeur "multipart/form-data", étant donné que dans le cas contraire, le navigateur ne reconnaît pas qu'il doit envoyer le fichier au serveur sous la forme codée correspondante. Si cette mention est manquante ou erronée, le formulaire sera traité tout à fait normalement, ce qui veut dire que le navigateur reçoit seulement le nom du fichier choisi et son chemin - mais pas son contenu. De plus, on peut aussi mentionner tout de suite dans le navigateur quels types de fichier peuvent être choisis et leur taille maximale en octets, encore que ces fonctions soient assez faciles à contourner. C'est pourquoi dans l'exemple a été incluse côté serveur une demande de ces paramètres, qui ne se laissent pas contourner.

vers le hautvers le bas 

Sécurité

Pour exclure un usage abusif des formulaires de fichier, il a été exigé (et également respecté par les fabricants de navigateur) qu'il ne soit pas possible d'obtenir une valeur par défaut des champs de fichier. À titre de comparaison, un champ "normal" peut être défini avec un texte par défaut: <input type="text" name="pardefaut" size="30" maxlength="30" value="texte par défaut">. Même contourner le problème à l'aide de JavaScript est impossible, comme par exemple définir dans un premier temps le champ comme champ de saisie à une ligne et y indiquer un fichier par défaut, puis modifier dans un second temps le type texte en type fichier à l'aide de l'événement onLoad, et envoyer par la suite le formulaire à l'appel de la méthode submit.

vers le hautvers le bas 

Exemple d'application

L'exemple qui suit reçoit le flux HTTP envoyé et l'exploite.

Le fichier est envoyé comme flux de données HTTP (Unicode) au serveur:

<html>
<head>
        <title>Transmission de fichier par ASP</title>
</head>
<body bgcolor="white">
<%=Font%>
<%
' --- ASP FileUpload Modul GetFILE (C) 1999 by Stefan Falz

' --- activer le traitement des erreurs
' --- On Error Resume Next
' --- affectation de la cause de l'erreur qui doit être affichée quand elle se produit
        Err.Source = "GetFILE HTTP-Upload"
' --- constante pour l'intitulé de l'erreur
        Const ErrHeader = "<b>erreur</b><br><br>"

' --- déclarer la liste
Dim ErrArray(4)
        ErrArray(0) = "10900 - Le fichier que vous envoyez est trop important."
        ErrArray(1) = "10901 - erreur inconnue".<br>
        ErrArray(2) = "10902 - Aucun fichier n'a été envoyé ou transmission défectueuse." <br>
        ErrArray(3) = "10903 - Aucun fichier texte n'a été transmis."<br>

' -- appel de la sous-routine GetFILE
        Call GetFILE()


Private Sub GetFile()

' --- cette sous-routine lit le flux HTTP


' --- déclaration des variables
Dim FileText
    FileText = Request.BinaryRead(Request.TotalBytes)
Dim FileTextByte
    FileTextByte = ""
Dim FileTextNew
    FileTextNew = ""
Dim FilePosFirst
    FilePosFirst = 0
Dim FilePosLast
    FilePosLast = 0
Dim FileType
    FileType = ""
Dim strRevText
    strRevText = ""
Dim strFileName
    strFileName = ""
Dim strFileNameOnly
    strFileName = ""
Dim posFileName
    posFileName = 0
Dim rghFile
    rghFileName = ""
Dim lenFileTextByte
    lenFileTextByte = 0

' --- mention de la taille maximale + environ  500 octets pour les informations de fichier
Dim maxLength
    maxLength = 25500

' --- demande de la taille du flux envoyé
        If Request.TotalBytes > maxLength Then
                Call Error_Handler(10900)
                Exit Sub
        End if

' --- recherche du code hexadécimal 0D 0A 0D 0A (début du fichier dans un flux HTTP)
        FilePosFirst = InStrB(FileText, (ChrB(13) & ChrB(10) & ChrB(13) & ChrB(10)))

' --- recherche du code hexadécimal 0D 0A 2D 2D (fin du fichier dans un flux HTTP)
        FilePosLast = InStrB(FileText, (ChrB(13) & ChrB(10) & ChrB(45) & ChrB(45)))

' --- recherche du code hexadécimal 2D 0A 0D à l'intérieur du flux HTTP inversé, étant donné
' --- que selon les circonstances, il peut y avoir plusieurs signes de fin de fichier.
        strRevText = StrReverse(FileText)
        FilePosLast = InStrB(strRevText, (ChrB(45) & ChrB(10)) & ChrB(13))
        FilePosLast = LenB(FileText) - FilePosLast

' --- Interruption si la taille du fichier est 0 octet
        If FilePosFirst = 0 Or FilePosLast = 0 Or FilePosLast - FilePosFirst < 5 Then
                Call Error_Handler(10902)
                Exit Sub
        End If
' --- Interruption si la mention "Content-Disposition=text/html" manque
        If InStrB(FileText, ChrB(67) & ChrB(111) & ChrB(110) & ChrB(116) & ChrB(101) & ChrB(110) & ChrB(116) & ChrB(45) & ChrB(84) & ChrB(121) & ChrB(112) & ChrB(101) & ChrB(58) & ChrB(32) & ChrB(116) & ChrB(101) & ChrB(120) & ChrB(116) & ChrB(47)) = 0 Then
                Call Error_Handler(10903)
                Exit Sub
        End if
' --- Interruption, lorsqu'une erreur survient qui ne fait pas partie de la liste ci-dessus
        If Err.Number <> 0 Then
                Call Error_Handler(10901)
                Exit Sub
        End if
' --- Recherche du nom de fichier chemin compris dans le flux HTTP
        posFileName = InStrB(FileText, ChrB(102) & ChrB(105) & ChrB(108) & ChrB(101) & ChrB(110) & ChrB(97) & ChrB(109) & ChrB(101) & ChrB(61) & ChrB(34)) + 9

        rghFileText = RightB(FileText, LenB(FileText) - posFileName)

        strFileName = LeftB(rghFileText, InStrB(rghFileText, ChrB(34)) - 1)
                Response.Write "<strong>nom de fichier chemin compris: </strong>"
                        Response.BinaryWrite strFileName
                Response.Write "<br>"

' --- Recherche du nom de fichier sans le chemin dans le flux HTTP
        posLastSlash = InStrB(StrReverse(strFileName), ChrB(92))

        strFileNameOnly = MidB(strFileName, LenB(strFileName) - posLastSlash, posLastSlash + 1)

                Response.Write "<strong>le nom de fichier sans son chemin: </strong>"
                        Response.BinaryWrite strFileNameOnly
                Response.Write "<br>"
' --- interruption si une erreur intervient
        If Err <> 0 Then
                Call Error_Handler(10901)
                Exit Sub
        End if

' --- écriture du contenu du fichier dans une liste d'octets
        FileTextByte = MidB(FileText, (FilePosFirst + 4), (FilePosLast - (FilePosFirst + 4)))

' --- Recherche de la taille du fichier par la lecture de la longueur du contenu de fichier trouvé
        lenFileTextByte = LenB(FileTextByte)

' --- Conversion du contenu de fichier (flux binaire) en signes  Ascii
        For i = 1 To lenFileTextByte
                FileTextNew = FileTextNew & Chr(AscB(MidB(FileTextByte, i, 1)))
        Next

' --- écriture dans un fichier du contenu du fichier trouvé.
        Set objFileSys = Server.CreateObject("Scripting.FileSystemObject")
                Set File = objFileSys.CreateTextFile(Server.MapPath("./") & "\" & Session.SessionID & ".tmp", True, False)
                        File.WriteLine CStr(FileTextNew)
                        File.Close
                Set File = Nothing
        Set objFileSys = Nothing

' --- sortie de la taille du fichier en octets
        Response.Write "<strong>taille du fichier: </strong>" & lenFileTextByte & " octets.<br><br>"

' --- conversion du contenu du fichier étant donné que les pages HTML ne sont pas affichées correctement
        FileTextNew = Replace(FileTextNew, "<", "&lt;")
        FileTextNew = Replace(FileTextNew, ">", "&gt;")
        FileTextNew = Replace(FileTextNew, VbCrLf, "<br>" & VbCrLf)
        FileTextNew = Replace(FileTextNew, Chr(9), "&nbsp;&nbsp;&nbsp;&nbsp;")

' --- sortie du contenu du fichier
        Response.Write FileTextNew
End Sub

Private Sub Error_Handler(intErrNumber)
' --- recherche du code d'erreur transmis et sortie à l'écran
        Select Case intErrNumber
                Case 10900: Response.Write ErrHeader & ErrArray(0)
                Case 10901: Response.Write ErrHeader & ErrArray(1)
                Case 10902: Response.Write ErrHeader & ErrArray(2)
                Case 10903: Response.Write ErrHeader & ErrArray(3)
                Case Else: Response.Write ErrHeader & Err.Description
        End Select
        Exit Sub
End Sub
%>
</body>
</html>

 

vers le hautvers le bas 

Essayez vous-même

choisir un fichier:
 

Remarque: Dans cet exemple ne sont acceptés que des fichiers texte (*.txt). Pour simplifier, les fichiers ne sont que renvoyés par le serveur au navigateur pour affichage à l'écran. Les fichiers pourraient tout aussi bien être sauvegardés sur le serveur.

vers le haut

© 2001-2005 Seite Informations