![]() |
Stefan Falz: |
|
|
|
| Adresse électronique: | |
| Présence Internet: |
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!
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.
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
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é à
http://www.asp-solutions.de.
<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>
|
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.
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.
L'exemple qui suit reçoit le flux HTTP envoyé et l'exploite.
<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, "<", "<")
FileTextNew = Replace(FileTextNew, ">", ">")
FileTextNew = Replace(FileTextNew, VbCrLf, "<br>" & VbCrLf)
FileTextNew = Replace(FileTextNew, Chr(9), " ")
' --- 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>
|