Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Upload di file: invio dei dati

Consentire all'utente di trasferire file su un server.
Consentire all'utente di trasferire file su un server.
Link copiato negli appunti

In molte occasioni sviluppando applicazioni Web ci si imbatte nella necessità di dover dare la possibilità agli utenti che utilizzano il web di spedire un file dal suo PC direttamente al server. Questa operazione in gergo viene definita UPLOAD.

Normalmente per implementare questa funzionalità ci si deve servire di componenti esterni che vengono eseguiti sul server. Purtroppo però questi componenti, oltre che avere un costo, necessitano di un'installazione da parte del fornitore di servizio sulle sue macchine; cosa che non sempre, anzi, molto raramente, avviene.

In questo articolo cercheremo di capire come effettuare le operazioni di upload senza utilizzare nessun componente esterno, ma servendoci unicamente degli strumenti messi a disposizione dal linguaggio.

Di cosa abbiamo bisogno

Beh, davvero di poco! Le condizioni da soddisfare in linea di massima sono 2:

  • avere un file da caricare
  • avere un posto dove metterlo

Per la prima condizione mi sembra davvero inutile aggiungere altro.

Per la seconda invece è fondamentale che lo spazio web a nostra disposizione abbia una cartella dove sono stati abilitati i permessi di scrittura in modo da poter posizionare i file che vengono uploadati.

Normalmente tutti gli spazi web comprendono una cartella che risponde a questi requisiti ma nel caso in cui quest'ultima non ci fosse, potete contattare il vostro fornitore di servizio e chiedergli di creare una cartella ed assegnarle i permessi di scrittura.

Spedire i dati (form.html)

Iniziamo dalla parte più semplice: recuperare i dati e spedirli. Dobbiamo dare la possibilità all'utente di inserire i dati, scegliere il file da spedire e inviarlo al server.

Per adesso potremmo dare la possibilità all'utente di spedire unicamente il file e un campo di testo ma in ogni caso si può anche inviare altro, come altri campi di testo, checkbox, e simili in modo da poterli utilizzare in seguito per essere inseriti in un database o semplicemente di visualizzati. Per fare questo ci serviremo di un semplice form.

<form action="upload.asp" method="post" enctype="multipart/form-data">
  CAMPO TESTO <input type="text" name="testo1">
  FILE <input type="file" name="file1">
  <input type="submit" value="Upload">
</form>

Come potete notare è un semplice form che chiama una pagina (upload.asp) dove verranno inserite le operazioni da effettuare.

N.B. Il form deve essere di tipo multipart/form-data condizione richiesta affinché vengano passati effettivamente i dati. Se noi impostassimo nel form unicamente il metodo POST senza specificare il tipo di formato verrebbe passato il valore contenuto nel campo file del form, e quindi unicamente il percorso del file ma non i dati in esso contenuti.

Recuperare i dati (upload.asp)

A questo punto i dati sono stati spediti dal PC client verso il server dove a loro volta dovranno essere recuperati. La prima cosa da verificare è quanti dati sono stati spediti dal client. Il recupero di qualsiasi informazione in ASP viene effettuato tramite l'oggetto Request ed i suoi metodi.

<% DatiRicevuti = Request.TotalBytes %>

Request.TotalBytes ci permette di conteggiare il numero totale dei byte che sono stati inviati tramite il form. Nel caso in cui volessimo visualizzare quanti dati sono stati spediti potremmo fare

<%
DatiRicevuti = Request.TotalBytes
Response.Write DatiRicevuti
%> 

Adesso sappiamo che i dati sono passati dal client al server ma in questo modo vengono solo conteggiati e non effettivamente elaborati. Per recuperarli effettivamente ci serviremo sempre dell'oggetto Request di ASP e di un altro particolare metodo di utilizzo : il BinaryRead.

Il metodo BinaryRead legge un certo numero di byte direttamente dal corpo della richiesta http inviato dal client come parte del metodo post. Il suo utilizzo:

variabile = Request.BinaryRead(numero_di_byte_da_leggere)

In questo caso dovendo leggere l'intero file e non solo una parte, non resta che conteggiare quanti byte sono stati spediti e memorizzarli in una variabile che sarà il nostro file:

<%
DatiRicevuti = Request.TotalBytes
File = Request.BinaryRead(DatiRicevuti)
%>

Nel caso in cui volessimo visualizzare quali dati sono stati spediti
potremmo fare:

<%
DatiRicevuti = Request.TotalBytes
File = Request.BinaryRead(DatiRicevuti)
Response.BinaryWrite File
%>

Ottenendo un risultato simile a questo:

-----------------------------7d21222e60 Content-Disposition:
form-data; name="testo1" davide-----------------------------7d21222e60
Content-Disposition: form-data; name="file1"; filename="C:WINDOWSDesktoptest.gif"
Content-Type: image/gif GIF89a22æ':[2á>|¯è÷"Eê [1] &möüy|Ã"óoÊYE?lÄïV?$c[¿~åÿ1êòbÃí>^"*‑|D¡ïfÃŒ|éø

Questo significa che è stato ricevuto qualcosa, quindi è gia possibile fare un primo controllo in modo da iniziare a far prendere forma a quello che sarà lo script definitivo.

<%
' Recupero il numero di byte ricevuti
DatiRicevuti = Request.TotalBytes
' Controllo che il numero di byte ricevuti sia > di 0
If DatiRicevuti > 0 Then
    ' Leggo i dati ricevuti
    File = Request.BinaryRead(DatiRicevuti)
  else
    ' Segnalo che non è stato ricevuto nulla
    Response.Write ("Non è stato inviato nessun file")
  End if
%> 

Intestazione del file

La serie di caratteri che è stata visualizzata, può apparire di scarso interesse, ma se viene analizzata meglio si può notare che non è altro che il nostro file con l'aggiunta di qualche informazione in più.

Quelle informazioni in più vengono raccolte nella prima e nell'ultima riga e costituiscono l'intestazione del file.

-----------------------------7d21222e60 Content-Disposition:
form-data; name="testo1" davide -----------------------------7d21222e60
Content-Disposition: form-data; name="file1"; filename="C:WINDOWSDesktoptest.gif"
Content-Type: image/gif

Analizzandole possiamo ottenere:

Frammento Descrizione
------------7d21222e60 Identificativo del file spedito
Content-Disposition: form-data Provenienza del file (form)
name="file" Nome del campo del form
filename="x:test.gif" Percorso e nome del del file
Content-Type: image/gif Tipologia del file spedito
Etc. Etc.

Tutto quello che rimane (tolto l'identificativo di chiusura) è il contenuto del file vero e proprio.

Nota: È importante ricordare che si sta lavorando con dati di tipo binario quindi tutte le operazioni che verranno effettuate su di questi dovranno essere effettuate come binarie.

Ad esempio la funzione Mid che normalmente restituisce il numero di caratteri specificato di una stringa verrà utilizzata come MidB in modo da poterla utilizzare con i dati byte inclusi in una stringa. Gli argomenti di questa funzione specificheranno quindi il numero di byte anziché il numero di caratteri. Per recuperare queste informazioni quindi dobbiamo analizzare la prima riga di dati ricevuta.

<%
DatiRicevuti = Request.BinaryRead(ByteRicevuti)

For i = 1 To lenB(DatiRicevuti)
  FileBinario = FileBinario & chr(ascB(midB(DatiRicevuti,i,1)))
Next

FirmaFile = left(FileBinario,instr(FileBinario,"" & vbCrLf)-1)
ArrPezzi = split(FileBinario,FirmaFile)

for pezzo = 1 to ubound(ArrPezzi)-1
  
  Inizio = instr(ArrPezzi(pezzo),"" & vbCrLf & "" & vbCrLf)
  Intestazione = left(ArrPezzi(pezzo),Inizio-1)
  Inizio = Inizio + len("" & vbCrLf) + len("" & vbCrLf)
  ContenutoFile = mid(ArrPezzi(pezzo),Inizio,len(ArrPezzi(pezzo))-Inizio-1)
' ...

In questo modo abbiamo tutto quello che ci serve non ci resta che controllare se gli altri campi spediti dal form contenevano qualcosa.

Per fare questo si deve utilizzare nuovamente la stringa di intestazione controllando gli altri campi quindi supponendo di dover controllare se un campo di testo del form denominato testo1 contiene qualcosa faremo:

if instr(Intestazione, "testo1") > 0 then
  text1 = ContenutoFile
end if 

e così via per tutti gli altri campi.

Scrivere il file

Per la scrittura del file utilizzeremo il FileSystemObject ormai abbiamo tutti i dati e non resta davvero altro da fare oltre che scrivere il file uploadato sul server in modo da completare le operazioni di upload.

Come al solito si effettua un controllo in modo da sapere se il campo del form che contiene il file (e che abbiamo chiamato file1) effettivamente sia stato utilizzato:

if instr(Intestazione,"file1") > 0 then

dopo di che si cerca il nome nell'intestazione del file spedito:

  i = InStr(Intestazione, "filename=")
  j = InStr(i + 10, Intestazione, chr(34))

  NomeUpload = Mid(Intestazione, i + 10, j - i - 10)
  
  i = InStrRev(NomeUpload,"")
  
  if i<>0 then
    NomeFile = mid(NomeUpload, i + 1)
  else
    NomeFile = NomeUpload
  end if 

e se il risultato delle operazioni ci fornisce un file allora viene scritto nella cartella del server:

  if NomeFile<>"" then
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Upload1 = True
    DimensioneFile1 = len(ContenutoFile)
    EstensioneFile1 = right(ContenutoFile,3)
    NomeFile1 = NomeFile
    Set textStream = FSO.CreateTextFile(server.mappath(NomeFile1), True, False)
  
    textStream.Write ContenutoFile
    textStream.Close
    Set textStream = Nothing
    Set FSO = Nothing
  end if
end if 

Lo stesso discorso vale anche per i campi dei file : nel caso in cui fossero presenti più campi file basta duplicare la condizione cambiando unicamente il nome del campo e delle variabili. Es.

if instr(Intestazione,"file2") > 0 then
  i = InStr(Intestazione,"filename=")
  j = InStr(i + 10,Intestazione,chr(34))
  
  NomeUpload = Mid(Intestazione,i + 10,j-i-10)
  
  i = InStrRev(NomeUpload,"")
  if i<>0 then
    NomeFile = mid(NomeUpload,i + 1)
  else
    NomeFile = NomeUpload
  end if
  
  if NomeFile<>"" then
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Upload2 = True
    DimensioneFile2 = len(ContenutoFile)
    EstensioneFile2 = right(ContenutoFile,3)
    NomeFile2 = NomeFile
    Set textStream = FSO.CreateTextFile(server.mappath(NomeFile2), True, False)
    textStream.Write ContenutoFile
    textStream.Close
    Set textStream = Nothing
    Set FSO = Nothing
  end if
end if 

A questo punto il file è stato ricevuto dal server e scritto quindi le operazioni di upload sono terminate.

Gli altri campi possono essere utilizzati a seconda di quello che serve, o per uploadare un altro file (se sono campi file), per inserire dei dati all'interno di database (se sono campi testo, dropdown, checkbox, ....), per spedire mail, oppure per qualsiasi altra necessità.

Scarica l'esempio di questo articolo

Ti consigliamo anche