Teil von SELFHTML aktuell Teil von Artikel Teil von PHP und ASP

Stefan Falz
Dateiupload per ASP

nach unten Stefan Falz
nach unten Voraussetzungen
nach unten Zum Thema
nach unten Anwendungsbeispiel
nach unten Testen Sie selbst

Stefan Falz

E-Mail: E-Mail i-service@falz.de
Homepage-URL: deutschsprachige Seite http://www.asp-solutions.de

Bei Fragen zu diesem Beitrag bitte den Autor des Beitrags kontaktieren!

nach obennach unten

Voraussetzungen

Bevor Sie beginnen, diesen Artikel zu lesen, möchte ich Sie gleich darauf hinweisen, daß einige Vorarbeiten nötig sind, um das Beispiel auf Ihrem lokalen Webserver oder einem Internetserver ausführen können. Als Betriebssystem wird Windows 95, Windows 98 oder Windows NT ab Version 4.0 vorausgesetzt. Weiterhin muß ein ASP-fähiger Webserver, wie z.B.: PersonalWebServer 4.0 oder InternetInformationServer ab Version 3.0 sowie ein ASP-Modul ab Version 4.02.0685 installiert sein. Frühere Versionen der genannten Komponenten unterstützen jeweils nur einen Teil der erforderlichen Routinen.

nach obennach unten

Zum Thema

Zu einem der noch eher gemiedenen Themen in der modernen Internetwelt gehört auch das direkte Hochladen von Dateien im Browser. Obwohl jeder ein Eingabeformular mit einem Eingabefeld für Dateien erstellen kann (siehe Seite Datei-Buttons in HTML), sieht man dies äußerst selten. Dies liegt zum einen daran, daß serverseitige Programme, die das Auslesen der Datei aus dem übermittelten HTTP-Stream und das anschließende Speichern der Datei auf dem Server übernehmen, recht teuer sind und wohl auch an der Tatsache, daß der Internetsurfer Schreibrechte auf einem Verzeichnis des Webservers benötigt, da unter ASP solche Aktionen mit dem Standardkonto IUSR_Rechnername vorgenommen werden. Aber auch diese Programme haben Ihre Berechtigung, da es mit ASP derzeit noch nicht möglich ist, Binärdateien, wie Bilder oder Programme zu speichern. Ein solches Modul, daß natürlich einiges mehr an Komfort, wie z.B automatische Übernahme der Sendedaten und der Dateinamen in eine Datenbank, automatische Zuordnung zu bestimmten Einträgen, usw. bereitstellt, finden Sie unter deutschsprachige Seite http://www.asp-solutions.de.

Datei senden.html

<html>
<head>
<title>Dateiupload per ASP</title>
</head>

<body>

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

Erläuterung:

Anders als in einem "normalen" Formular, in dem die Angabe enctype="..." entfallen kann, muß bei der Versendung von Dateien diese Angabe den Wert "multipart/form-data" haben, da der Browser ansonsten nicht erkennt, daß er die Datei entsprechend codiert an den Server senden soll. Bei fehlerhafter oder fehlender Angabe wird das Formular ganz normal behandelt, d.h. der Browser erhält lediglich den ausgewählten Dateinamen inkl. Pfad, aber nicht den Inhalt der Datei. Weiterhin kann man im Browser auch gleich angeben, welche Dateitypen ausgewählt werden dürfen und die max. Dateigröße in Byte, aber diese Funktionen lassen sich sehr leicht umgehen. Daher ist in dem Beispiel eine serverseitige Abfrage auf diese Parameter eingebaut, die sich nicht bestechen lassen.

nach obennach unten

Sicherheit

Um einen Mißbrauch der Dateiformulare auszuschließen, wurde gefordert (und das wurde von den Browserherstellern auch eingehalten), daß es keine Möglichkeit geben soll, die Dateifelder vorzubelegen. Zum Vergleich: ein "normales" Eingabefeld können Sie mit <input type="text" name="Vorbelegung" size="30" maxlength="30" value="Vorbelegung">. Auch Umwege über JavaScript sind nicht möglich, wie z.B. das Feld zuerst als Texteingabefeld zu deklarieren und vorzubelegen, und mit dem onLoad-Event der Datei den Typ von text in file zu ändern und anschließend das Formular durch Aufrufen der Methode submit zu versenden.

nach obennach unten

Anwendungsbeispiel

Das folgende Beispiel empfängt den gesendeten HTTP-Stream und wertet Ihn aus.

Datei wird als HTTP-Stream (Unicode) Server geschickt:

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

' --- Fehlerbehandlung aktivieren
' --- On Error Resume Next
' --- Zuweisen der Fehlerquelle, die bei einem Fehler ausgegeben werden soll
        Err.Source = "GetFILE HTTP-Upload"
' --- Konstante für Fehlerüberschrift
Const ErrHeader = "<b>Fehler</b><br><br>"

' --- Array deklarieren
Dim ErrArray(4)
        ErrArray(0) = "10900 - Ihre gesendete Datei ist zu groß."
        ErrArray(1) = "10901 - Unbekannter Fehler.<br>"
        ErrArray(2) = "10902 - Es wurde keine Datei gesendet oder die Übertragung ist fehlerhaft.<br>"
        ErrArray(3) = "10903 - Es wurde keine Textdatei gesendet.<br>"

' -- Aufrufen der Subroutine GetFILE
        Call GetFILE()


Private Sub GetFile()

' --- In dieser Subroutine wird der HTTP-Stream ausgelesen


' --- Deklarieren der Variablen
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

' --- Angeben der max. Dateigröße + ca. 500 Byte für Dateiinformationen
Dim maxLength
    maxLength = 25500

' --- Abfrage der Größe des gesendeten Streams
        If Request.TotalBytes > maxLength Then
                Call Error_Handler(10900)
                Exit Sub
        End if

' --- Suchen nach HexCode 0D 0A 0D 0A (Dateianfang innerhalb des HTTP-Streams)
        FilePosFirst = InStrB(FileText, (ChrB(13) & ChrB(10) & ChrB(13) & ChrB(10)))

' --- Suchen nach HexCode 0D 0A 2D 2D (Dateiende innerhalb des HTTP-Streams)
        FilePosLast = InStrB(FileText, (ChrB(13) & ChrB(10) & ChrB(45) & ChrB(45)))

' --- Suchen nach HexCode 2D 0A 0D innerhalb des umgedrehten HTTP-Streams, da unter
' --- Umständen mehrere Dateiendekennzeichen vorhanden sind.
        strRevText = StrReverse(FileText)
        FilePosLast = InStrB(strRevText, (ChrB(45) & ChrB(10)) & ChrB(13))
        FilePosLast = LenB(FileText) - FilePosLast

' --- Abbruch bei Dateigröße 0 Byte
        If FilePosFirst = 0 Or FilePosLast = 0 Or FilePosLast - FilePosFirst < 5 Then
                Call Error_Handler(10902)
                Exit Sub
        End If
' --- Abbruch bei fehlender Angabe "Content-Disposition"
        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
' --- Abbruch, wenn ein Fehler aufgetreten ist, der nicht zu den obigen Fehlern gehört
        If Err.Number <> 0 Then
                Call Error_Handler(10901)
                Exit Sub
        End if
' --- Ermittlung des Dateinamens inkl. Pfad innerhalb des HTTP-Streams
        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>Dateiname inkl. Pfad: </strong>"
                        Response.BinaryWrite strFileName
                Response.Write "<br>"

' --- Ermittlung des Dateinamens exkl. Pfad innerhalb des HTTP-Streams
        posLastSlash = InStrB(StrReverse(strFileName), ChrB(92))

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

                Response.Write "<strong>Dateiname exkl. Pfad: </strong>"
                        Response.BinaryWrite strFileNameOnly
                Response.Write "<br>"
' --- Abbruch, wenn ein Fehler aufgetrten ist
        If Err <> 0 Then
                Call Error_Handler(10901)
                Exit Sub
        End if

' --- Schreiben des Dateiinhalts in ByteArray
        FileTextByte = MidB(FileText, (FilePosFirst + 4), (FilePosLast - (FilePosFirst + 4)))

' --- Ermittlung der Dateigröße durch Auslesen der Länge des ermittelten Dateiinhalts
        lenFileTextByte = LenB(FileTextByte)

' --- Konvertierung des Dateiinhalts (Binärstream) in Ascii-Zeichen
        For i = 1 To lenFileTextByte
                FileTextNew = FileTextNew & Chr(AscB(MidB(FileTextByte, i, 1)))
        Next

' --- Schreiben des ermittelten Dateiinhalts in eine Datei.
        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

' --- Ausgeben der Dateigröße in Bytes
        Response.Write "<strong>Dateigr&ouml;&szlig;e: </strong>" & lenFileTextByte & " Byte.<br><br>"

' --- Konvertieren des Dateiinhalts, da HTML-Seiten nicht korrekt angezeigt werden
        FileTextNew = Replace(FileTextNew, "<", "&lt;")
        FileTextNew = Replace(FileTextNew, ">", "&gt;")
        FileTextNew = Replace(FileTextNew, VbCrLf, "<br>" & VbCrLf)
        FileTextNew = Replace(FileTextNew, Chr(9), "&nbsp;&nbsp;&nbsp;&nbsp;")

' --- Ausgabe des Dateiinhalts
        Response.Write FileTextNew
End Sub

Private Sub Error_Handler(intErrNumber)
' --- Ermitteln des übergebenen Fehlercodes und Ausgabe am Bildschirm
        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>

nach obennach unten

Testen Sie selbst

Datei auswählen:

Hinweis: in diesem Beispiel werden nur Textdateien (*.txt) akzeptiert. Die Dateien werden der Einfachheit halber vom Server nur an den Browser zur Anzeige am Bildschirm zurückgegeben. Die Dateien könnten aber ebensogut auf dem Server gespeichert werden.

Teil von SELFHTML aktuell Teil von Artikel Teil von PHP und ASP

© 2007 bereichsübergreifende Seite Impressum