BearbeitenProblem
Ich möchte eine Datei zum Download anbieten. Und/oder ich will vermeiden dass sie im Browser angezeigt wird.
BearbeitenLö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.
BearbeitenBeispiele zum Testen
- WORDTEXT.DOC herunterladen: <a href="sendfile.asp?datei=wordtext.doc">
- ACROBAT.PDF herunterladen: <a href="sendfile.asp?datei=unterhalbvirtdir/acrobat.pdf">
- Natürlich auch mit html: <a href="/cgi-bin/sendfile.asp?file=sendfile.htm">
- Versuchen darf man, aber ... : <a href="sendfile.asp?file=sendfile.asp">
- Bildchen herunterladen, nicht anzeigen: <a href="sendfile.asp?datei=sob.jpg">
- SCHULUNG.CSS herunterladen: <a href="sendfile.asp?datei=format.css">
- 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""> " & _
"<a href=""/afolder/sendfile.asp?file=page.htm"">Download</a> " & _
"</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