AspGerman Wiki

Bearbeiten

Problem

Ich möchte eine Datei zum Download anbieten. Und/oder ich will vermeiden dass sie im Browser angezeigt wird.

Bearbeiten

Lösung das angehängte Script

Aus Sicherheitsgründen ist ein bischen Anpassung notwendig. Die Konstante "ForcedVirtDir" sollte das Verzeichnis enthalten von dem man Downloaden darf. Andernfalls könnte jemand auf die glorreiche Idee kommen und sich alle Dateien vom Server (zumindest in der webroot) anzeigen zu lassen. Die inflexible Beschränkung auf ein Verzeichnis wäre theoretisch schnell behoben. Wenn der Tag mehr Stunden hätte, wäre es auch gleich passiert.

Bearbeiten

Beispiele zum Testen

  1. WORDTEXT.DOC herunterladen: <a href="sendfile.asp?datei=wordtext.doc">
  2. ACROBAT.PDF herunterladen: <a href="sendfile.asp?datei=unterhalbvirtdir/acrobat.pdf">
  3. Natürlich auch mit html: <a href="/cgi-bin/sendfile.asp?file=sendfile.htm">
  4. Versuchen darf man, aber ... : <a href="sendfile.asp?file=sendfile.asp">
  5. Bildchen herunterladen, nicht anzeigen: <a href="sendfile.asp?datei=sob.jpg">
  6. SCHULUNG.CSS herunterladen: <a href="sendfile.asp?datei=format.css">
  7. Powerpointshow local im Fullscreen starten: <a href="sendfile.asp?datei=witzig.pps

<%@ Language=VBScript EnableSessionState=False%>
<%
 Option Explicit

 Dim i, sfile, fso, oFile, sExt, oStream
 Const adTypeBinary = 1
 Const adTypeText = 2
 Const ForcedVirtDir = "/bc/"  ' --- aus Sicherheitsgründen nicht von überall

 sFile = Trim(Request("file"))
 If sFile = "" Then   ' - eine zweite Chance
   sFile = Trim(Request("datei"))
 End If

 If sFile = "" Then
   Usage
   Response.end
 Else
   ' --- sicherheitshalber alle Pfadangaben verwerfen
   sFile = GetFileName(sFile)

   Set fso = CreateObject("Scripting.FileSystemObject")
   If Not fso.FileExists(Server.Mappath(ForcedVirtDir & sFile)) Then
     FileNotFound sFile
     Response.end
   Else
     sExt = getExt(sFile)
     If Lcase(sExt) = "asp" or Lcase(sExt) = "aspx" Then
       NoASP
       Response.End
     End If
   End If
 End If

 ' --- jetzt geht es aber tatsächlich los
 Response.Buffer = True
 Response.Clear
 Response.Expires = 0
 Response.ContentType = "Download-Datei"
 Response.AddHeader "Content-Disposition","attachment; filename=" & sFile

 Set oStream = Server.CreateObject("ADODB.Stream")
 oStream.Type = adTypeBinary
 oStream.Open
 oStream.LoadFromFile(Server.MapPath(ForcedVirtDir & sFile))
 Response.AddHeader "Content-Length", oStream.Size  ' -- Schönheit
 Response.BinaryWrite oStream.Read(oStream.Size)
 oStream.Close
 Set oStream = Nothing

 Response.Flush
 Response.End

' *******************
'  aus is
' *******************

Function GetExt (sString)
 Dim i
 i = InStrRev (sString, ".")
 If i > 0 Then
   getExt = mid(sString, i+1)
 Else
   getExt = ""
 End If
End function

Function GetFileName (sString)
  Dim i
  i = InStrRev (sString, "/")
  If i > 0 Then
    getFileName = mid(sString, i+1)
  Else
    getFileName = sString
  End If
End function

Sub Usage()
  response.write "<html><head><title>Sendfile</title></head><body><h3>Sendfile Usage: </h3> " & _
"<blockquote><p>Please tell sendfile the file to be downloaded.  " & _
"For Example: </p><p><font face=""Courier"" color=""#0000FF""> " & _
"&lt;a href=&quot;&quot;/afolder/sendfile.asp?file=page.htm&quot;&quot;&gt;Download&lt;/a&gt; " & _
"</font></p></blockquote></body></html> "
End Sub

Sub FileNotFound(sRequest)
  response.write "<html><head><title>Sendfile</title></head><body><h3>Sendfile Error: </h3> " & _
"<blockquote><p>Could not find the requested file <b><i>" & sRequest & "</i></b></p>" & _
"<p>Please check Filename. Also note this script can only send files from the " & _
        ForcedVirtDir & " directory.</p></blockquote></body></html> "
End Sub

Sub NoASP()
  response.write "<html><head><title>Sendfile</title></head><body><h3>Sendfile Hint: </h3> " & _
"<blockquote><p>ASP[X] files cannot be sent due to security reasons. Sorry!" & _
"</blockquote></body></html> "
End Sub
%>

Wer sich über den komischen Content-Type "Download-Datei" wundert. In einer größeren Testkette mit div. Browsern auf unterschiedlichen Betriebssystemen stellte sich das als der gangbarste Kompromis heraus. Alle neueren Browser würden einen korrekten Content-Type verstehen. Ein paar ältere Kollegen habe da ihre eigene Interpretation. Tja und am Ende wird in einigen Fällen diese Content-Type angezeigt und da ist der erwähnte der Sinnigste für den Benutzer

ScrewTurn Wiki version 2.0.33. Some of the icons created by FamFamFam.