Ladda upp filer via asp utan komponent
Förord
Det har många gånger pratats om hur man skall göra för att användaren skall kunna ladda upp egna filer till en server. I många fall har inte detta gått då man varit tvingad till att köpa och installera en tredjeparts programvara och din ISP har i de flesta fall inte velat göra detta.Innehåll
»»
»
»
»
»
»
Relaterade artiklar
» Ladda upp filer via asp # 2 Spara på olika sättNu är det så att du faktiskt kan göra ett sådant system alldeles själv utan att behöva beblanda dig med vad servern har eller inte. Är det en Internet Information Server så kan du faktiskt klara av det själv. Du behöver dock eventuellt hjälp av din server provider med att ställa om rättigheterna på en av dina filkataloger så att användaren Guest eller INET_USRxxxx får tillgång att skriva till en katalog för annars kommer inte filen att tillåtas bli sparad på din server.
Nu sätter vi igång och tittar på vad vi behöver göra för att klara av detta. Du börjar med att göra ett formulär där användaren kan välja en fil och sedan trycka på skicka. För detta behöver vi en html eller asp-fil som vi använder oss av.
Ovanstående exempel använder sig av något som skiljer sig från en vanlig form, nämligen i form-taggen så används något som heter enctype attributet innehållandet värdet "multipart/form-data". Detta specificerar hur vi vill att postningen skall ske. Skriver du inte detta så kommer vi inte att få tag i filen, inte heller kommer knappen "bläddra" automatiskt upp för att kunna välja den fil vi skall skicka upp.
Obs! Jag bör även tillägga att om du försöker att göra ett förval i textboxen med ett filnamn eller liknande så går det inte för den är read-only. jag har sett script som skall kunna fixa detta för Netscape, men inte explorer.
I detta exempel har jag även lagt till två alternativ, ett att du kan använda filnamnet såsom det är på din dator - eller att du själv bestämmer ett annat namn som filen kommer sparas med.
Hur ser den postade headern ut?
Så här ser headern ut när man postar den. Här ser du alla fältnamn, värdet på dom och som du ser så är det också ; som separerar fält och värden vilket gör det enkelt för oss att plocka ut detta med hjälp av vb-scriptets split-funktion.
-----------------------------7d117c2c490276
Content-Disposition: form-data; name="test"; filename=
"C:\testDoc.txt"
Content-Type: text/plain
test upload file.
-----------------------------7d117c2c490276
Content-Disposition: form-data; name="filename"
userSpecified
-----------------------------7d117c2c490276
Content-Disposition: form-data; name="userSpecifiedName"
Test.txt
-----------------------------7d117c2c490276--
Nu är det dags att presentera programkoden. Jag har separerat programmet i flera delar för att enklare kunna förklara vad det är som händer för varje sektion. Klipp ut alla delar och skapa en fil som heter upload.asp. Nu börjar vi först med vår header:
Nu är det dags att hämta filen från användaren genom att skriva ett asp-script som dels hämtar filen och därefter sparar den på din server. Scriptet börjar med att tillåta serven extra tid innan den gör timeout. Ju större filer som tillåts, desto mer tid kommer att behövas. Skulle det vara så att ditt script gör timeout innan filen laddats över kommer den att försvinna. Vi sätter även upp några konstanter som används i delar av funktionerna.
(Alla dessa rutor med programkod hänger ihop så klistra in dom efter varandra på din asp-sida som du döper till upload.asp)
Det första som händer är att scriptet hämtar all data som postats från html-filen och placerar det i en variabel som heter binData. Detta görs genom att använda metoden BinaryRead från Request objektet. Denna metod läser alltså ett visst antal tecken från headern som postats i binärt format. Hur många bytes som skall läsas får vi reda på genom att köra TotalBytes från Request objektet.
Något som kan vara lite underligt är att om du väl läst headern så kan du inte komma åt den information som fanns innan du postade filen som du vanligtvis gör med Request.Form eller Request.QueryString - och samma sida är det om du istället kör Request, då kan du inte komma åt headern binärt. Det betyder att du kan inte mixa hur du skall posta din data.
Kontrollerar att formen submittats korrekt:
En fil som postas via ett formulär kan endast hämtas om du i form-taggen använt "multipart/form-data". För att försäkra oss om att så även är fallet denna gång så kontrollerar vi det genom att leta efter just den strängen. Om det är ok, så börjar vi att hämta in alla de fält och det som skrivits på formen:
Nu är det äntligen dags att börja hämta filen. Men vi måste först ta reda på vilket fält som innehåller filnamn, vilket som innehåller text och information, detta gör vi med att iterera i alla variabler, leta efter ordet filename - då har vi filen. Exemplet nedan visar hur det kan se ut om det är fler än en fil som skickas upp, fast vi inte tagit tak för det i formuläret där vi postade informationen.
Vi använder nu FSO för att göra i ordning det filnamn som vi skall spara filen med. För säkerhets skull kontrollerar vi även om det kan vara skickat från någon annan dator än PC, nämligen Machintosh - då skiljer sig filnamnen genom att Windows skickar med hela sökvägen och filnamnet medans Mac endast skickar filnamnet. Först kontrollerar vi om vi skall spara filen med det ursprungliga namnet eller om vi skall använda det som användaren valt att spara filen med. Därefter bygger vi ihop filnamnet så det passar vårt syfte.
Nu har vi lagrat hela filen i en array och det är dags att skriva ner den till servern. Vi börjar med att sätta sökvägen, därefter skapa en tom fil och genom det kan vi också skriva ner filen till disk. Observera det jag skrev tidigare - du måste ha skrivrättigheter för användaren Guest eller INET_USRxxx på den katalog som filen skall sparas.
Nu är hela scriptet klart och det är brukligt att berätta om filen laddades upp korrekt eller om något gick fel. Här kan du välja att i slutet av programmet skriva ett meddelande, göra en Redirect till en annan sida eller vad du vill göra.
Avslutningsvis
För att jag skall veta om kursen är bra eller om den måste skrivas om så rösta gärna här uppe till höger. Skicka gärna ett iMail om du vill kommentera något som är felaktigt eller du tycker borde förtydligas.
/Pelle Johansson
Nivå: (3) Avancerad
Du behöver:
Microsoft IIS 3x eller PWS.
Skapa filen main.asp
Nu sätter vi igång och tittar på vad vi behöver göra för att klara av detta. Du börjar med att göra ett formulär där användaren kan välja en fil och sedan trycka på skicka. För detta behöver vi en html eller asp-fil som vi använder oss av.
Ladda upp filer med ASP
Ovanstående exempel använder sig av något som skiljer sig från en vanlig form, nämligen i form-taggen så används något som heter enctype attributet innehållandet värdet "multipart/form-data". Detta specificerar hur vi vill att postningen skall ske. Skriver du inte detta så kommer vi inte att få tag i filen, inte heller kommer knappen "bläddra" automatiskt upp för att kunna välja den fil vi skall skicka upp.
Obs! Jag bör även tillägga att om du försöker att göra ett förval i textboxen med ett filnamn eller liknande så går det inte för den är read-only. jag har sett script som skall kunna fixa detta för Netscape, men inte explorer.
I detta exempel har jag även lagt till två alternativ, ett att du kan använda filnamnet såsom det är på din dator - eller att du själv bestämmer ett annat namn som filen kommer sparas med.
Hur ser den postade headern ut?
Så här ser headern ut när man postar den. Här ser du alla fältnamn, värdet på dom och som du ser så är det också ; som separerar fält och värden vilket gör det enkelt för oss att plocka ut detta med hjälp av vb-scriptets split-funktion.
-----------------------------7d117c2c490276
Content-Disposition: form-data; name="test"; filename=
"C:\testDoc.txt"
Content-Type: text/plain
test upload file.
-----------------------------7d117c2c490276
Content-Disposition: form-data; name="filename"
userSpecified
-----------------------------7d117c2c490276
Content-Disposition: form-data; name="userSpecifiedName"
Test.txt
-----------------------------7d117c2c490276--
Upload.asp
Nu är det dags att presentera programkoden. Jag har separerat programmet i flera delar för att enklare kunna förklara vad det är som händer för varje sektion. Klipp ut alla delar och skapa en fil som heter upload.asp. Nu börjar vi först med vår header:Nu är det dags att hämta filen från användaren genom att skriva ett asp-script som dels hämtar filen och därefter sparar den på din server. Scriptet börjar med att tillåta serven extra tid innan den gör timeout. Ju större filer som tillåts, desto mer tid kommer att behövas. Skulle det vara så att ditt script gör timeout innan filen laddats över kommer den att försvinna. Vi sätter även upp några konstanter som används i delar av funktionerna.
(Alla dessa rutor med programkod hänger ihop så klistra in dom efter varandra på din asp-sida som du döper till upload.asp)
<%
' Justera tiden beroende på hur stora filer du kommer tillåta att skicka
Server.ScriptTimeout = 5400
Const ForWriting = 2
Const TristateTrue = -1
CrLf = Chr(13) & Chr(10)
Funktionen för att hämta ut ett värde av ett specifikt fältnamn:
'Denna funktion hämtar ett fälts namn
Function GetFieldName(infoStr)
sPos = InStr(infoStr, "name=")
EndPos = InStr(sPos + 6, infoStr, Chr(34) & ";")
If EndPos = 0 Then
EndPos = inStr(sPos + 6, infoStr, Chr(34))
End If
GetFieldName = Mid(infoStr, sPos + 6, endPos - (sPos + 6))
End Function
Funktion för att hämta ut filnamnet från den postade formen:
'Denna funktion hämtar fältets värde i filnamn
Function GetFileName(infoStr)
sPos = InStr(infoStr, "filename=")
EndPos = InStr(infoStr, Chr(34) & CrLf)
GetFileName = Mid(infoStr, sPos + 10, EndPos - (sPos + 10))
End Function
Funktionen för att kontrollera att filen är av typen MIME:
' Denna funktion hämtar ett filens MIMEtyp
Function GetFileType(infoStr)
sPos = InStr(infoStr, "Content-Type: ")
GetFileType = Mid(infoStr, sPos + 14)
End Function
Nu är det dags för själva huvudprogrammet:
Det första som händer är att scriptet hämtar all data som postats från html-filen och placerar det i en variabel som heter binData. Detta görs genom att använda metoden BinaryRead från Request objektet. Denna metod läser alltså ett visst antal tecken från headern som postats i binärt format. Hur många bytes som skall läsas får vi reda på genom att köra TotalBytes från Request objektet.Något som kan vara lite underligt är att om du väl läst headern så kan du inte komma åt den information som fanns innan du postade filen som du vanligtvis gör med Request.Form eller Request.QueryString - och samma sida är det om du istället kör Request, då kan du inte komma åt headern binärt. Det betyder att du kan inte mixa hur du skall posta din data.
PostData = ""
' Hämtar hela headern som postats genom att hämta headerns storlek med dess data
Dim biData
biData = Request.BinaryRead(Request.TotalBytes)
' Tänk nu på att det är binär data så vi måste ändra detta till
' någonting som är hanterbart och läsbart.
For nIndex = 1 to LenB(biData)
PostData = PostData & Chr(AscB(MidB(biData,nIndex,1)))
Next
' När du använt BinaryRead så kan du inte använda Request-objektet. Därför måste vi
' hantera alla request-variablerna själva genom att hämta ut detta
ContentType = Request.ServerVariables( "HTTP_CONTENT_TYPE")
' delar upp datat
ctArray = Split(ContentType, ";")
Kontrollerar att formen submittats korrekt:
En fil som postas via ett formulär kan endast hämtas om du i form-taggen använt "multipart/form-data". För att försäkra oss om att så även är fallet denna gång så kontrollerar vi det genom att leta efter just den strängen. Om det är ok, så börjar vi att hämta in alla de fält och det som skrivits på formen:
' En fil som postas fungerar endast om du i formen satt "multipart/form-data"
' - så vi kontrollerar att det är gjort
If Trim(ctArray(0)) = "multipart/form-data" Then
ErrMsg = ""
' Hämta all data om formen
bArray = Split(Trim(ctArray(1)), "=")
Boundary = Trim(bArray(1))
' Splitta upp all denna indata
FormData = Split(PostData, Boundary)
' Dela upp informationen för varje variabel och data
Dim myRequest, myRequestFiles(9, 3)
Set myRequest = CreateObject("Scripting.Dictionary")
FileCount = 0
För varje fält som postats:
Nu är det äntligen dags att börja hämta filen. Men vi måste först ta reda på vilket fält som innehåller filnamn, vilket som innehåller text och information, detta gör vi med att iterera i alla variabler, leta efter ordet filename - då har vi filen. Exemplet nedan visar hur det kan se ut om det är fler än en fil som skickas upp, fast vi inte tagit tak för det i formuläret där vi postade informationen.
' För varje fält som finns i den postade formen
For x = 0 to UBound(FormData)
' Två CrLf markerar slutet på informationen om ett fält. Allt efter
' det är ett värde
InfoEnd = InStr(FormData(x), CrLf & CrLf)
If InfoEnd > 0 Then
' Hämtar informationen för aktuellt fält utom skräptecken i slutet på strängen
varInfo = Mid(FormData(x), 3, InfoEnd - 3)
' Hämtar värdet på fältet, vi tar bort CrLf både i början och i slitet
varValue = Mid(FormData(x), InfoEnd + 4,Len(FormData(x)) - InfoEnd - 7)
' Är detta filen eller fältet
If (InStr(varInfo, "filename=") > 0) Then
' placera vår fil i en stor array.
' Om du vill ladda upp flera filer på en gång så visas här hur du
' kan göra, men formen du postade från tillåter bara en så då får
' du göra om den så fler filen kan postas.
myRequestFiles(FileCount, 0) = GetFieldName(varInfo)
myRequestFiles(FileCount, 1) = varValue
myRequestFiles(FileCount, 2) = GetFileName(varInfo)
myRequestFiles(FileCount, 3) = GetFileType(varInfo)
FileCount = FileCount + 1
Else
' Detta är ett vanligt fält
myRequest.add GetFieldName(varInfo), varValue
End If
End If
Next
Else
ErrMsg = "Du har fel encoding typ!"
End If
Instansierar FSO och gör i ordning filnamnet:
Vi använder nu FSO för att göra i ordning det filnamn som vi skall spara filen med. För säkerhets skull kontrollerar vi även om det kan vara skickat från någon annan dator än PC, nämligen Machintosh - då skiljer sig filnamnen genom att Windows skickar med hela sökvägen och filnamnet medans Mac endast skickar filnamnet. Först kontrollerar vi om vi skall spara filen med det ursprungliga namnet eller om vi skall använda det som användaren valt att spara filen med. Därefter bygger vi ihop filnamnet så det passar vårt syfte.
' Om du tillåter mer filer än 1, gör om detta till en loop
' instansierar File ScriptingSystem (FSO)
Set lf = server.createObject("Scripting.FileSystemObject")
' vad valde användaren att använda för filnamn?
If myRequest("filename") = "original" Then
' Vad är det för klient som skickar filen, Machintosh skickar endast filnamnet
' medan Windows även skickar med sökvägen till filen.
BrowserType = UCase(Request.ServerVariables("HTTP_USER_AGENT"))
If (InStr(BrowserType, "WIN") > 0) Then
' Det är Windows med sökväg i
sPos = InStrRev(myRequestFiles(0, 2), "\")
fName = Mid(myRequestFiles(0, 2), sPos + 1)
End If
If (InStr(BrowserType, "MAC") > 0) Then
' Det är mac, endast filnamnet skickas
fName = myRequestFiles(0, 2)
End If
' här skapar du filnamnet som vi skall använda
FilePath = "./" & fName
Else
' använd det filnamn som användaren skrev istället
' Om användaren valt att spara med ett eget filnamn,
' då tar vi det istället.
FilePath = "./" & myRequest("userSpecifiedName")
End If
Sparar filen fysiskt på disken
Nu har vi lagrat hela filen i en array och det är dags att skriva ner den till servern. Vi börjar med att sätta sökvägen, därefter skapa en tom fil och genom det kan vi också skriva ner filen till disk. Observera det jag skrev tidigare - du måste ha skrivrättigheter för användaren Guest eller INET_USRxxx på den katalog som filen skall sparas.
' anger sökvägen dit filen skall sparas
SavePath = Server.MapPath(FilePath)
' skapar objektet för att kunna spara en fil, finns den så skriver vi över den
Set SaveFile = lf.CreateTextFile(SavePath, True)
' Skriver filen (arrayen) till disk
SaveFile.Write(myRequestFiles(0, 1))
' stänger och frigör objektet
SaveFile.Close
%>
Tackar eller presenterar ett felmeddelande:
Nu är hela scriptet klart och det är brukligt att berätta om filen laddades upp korrekt eller om något gick fel. Här kan du välja att i slutet av programmet skriva ett meddelande, göra en Redirect till en annan sida eller vad du vill göra.
<% If ErrMsg = "" Then %>
Tack för din fil, den har nu laddats upp!
<% Else %>
<%= ErrMsg %>
<% End If %>
Avslutningsvis
För att jag skall veta om kursen är bra eller om den måste skrivas om så rösta gärna här uppe till höger. Skicka gärna ett iMail om du vill kommentera något som är felaktigt eller du tycker borde förtydligas.
/Pelle Johansson
Nivå: (3) Avancerad
Du behöver:
Microsoft IIS 3x eller PWS.
0 Kommentarer