Reindirizzamenti in HTTP

L'URL redirection, anche conosciuto come URL forwarding, è una tecnica che serve a dare più di un indirzzo URL ad una pagina, un form, oppure un intero sito o applicazione. L'HTTP ha uno speciale tipo di risposta, chiamata HTTP redirect, per questa operazione.
I redirect portano a termine molti scopi:
  • Reindirizzamenti temporanei quando un sito è spento o in manutenzione
  • Reindirizzamenti permanenti per preservare link o bookmark esistenti dopo il cambio dell'URL del sito, pagine di elaborazione mentre viene caricato un file, ecc.

Principio

In HTTP, il reindirizzamento è causato da un server che manda una speciale risposta redirect ad una richiesta. Le riposte di reindirizzamento hanno dei codici di stato che iniziano con un 3, e un Location header contenente l'URL a cui deve essere reindirizzato.

Quando i browser ricevono un reindirizzamento, caricano immediatamente il nuovo URL assegnatogli nel Location header. Inoltre visto che l'impatto di questa operazione è così basso, gli utenti non notano quasi mai il reindirizzamento.

Ci sono molti tipi di reindirizzamenti, raggruppati in tre categorie:

  1. Reindirizzamenti permanenti
  2. Reindirizzamenti temporanei
  3. Reindirizzamenti speciali

Reindirizzamenti permanenti

Questi reindirizzamenti sono stati creati per rimanenere per sempre. Implicano che l'URL originale non dovrebbe più essere usato, e dovrebbe essere rimpiazzato da uno nuovo. I motori di ricerca, i lettori RSS e altri crawler aggiorneranno l'URL originale per la risorsa.

Codice Testo Gestione del metodo Caso d'uso tipico
301

Moved Permanently

(Spostato Permanentemente)

GET metodi non cambiati.
Altri potrebbero o meno essere cambiati in GET.[1]
Riorganizzazione di un sito web.
308

Permanent Redirect

(Reindirizzamento Permanente)

I metodi e il body non sono cambiati. Riorganizzazione di un sito web, con dei link o operazioni che non usufruiscono del GET.

[1] La specificazione non intendeva permettere il cambiamenti nei metodi, ma ci sono degli user agents esistenti che cambiano i loro metodi. 308 è stato creato per rimuovere l'ambiguità del comportamento quando vengono usati metodi che non usufruiscono del GET.

Reindirizzamenti temporanei

Qualche volta la risorsa richiesta non può essere raggiunta dal suo luogo originale, ma può essere raggiunta da un'altro luogo. In questo caso, un reindirizzamento temporaneo può essere usato.

I motori di ricerca e altri crawler non memorizzano il nuovo URL temporaneo. Reindirizzamenti temporanei vengono anche usati quando vengono create, aggiornate, o eliminate delle risorse, per mostrare pagine di avanzamento temporanee.

Codice Testo Gestione del metodo Casi d'uso tipici
302

Found

(Trovato)

GET metodi non cambiati.
Altri potrebbero o meno essere cambiati in GET.[2]
La pagina web non è disponibile temporaneamente per ragioni non previste.
303

See Other

(Vedi altro)

GET metodi non cambiati.
Altri cambiati a GET (body perso).
Usato per reindirizzare dopo un PUT o un POST, In modo che l'aggiornamento della pagina non causi nuovamente l'operazione.
307

Temporary Redirect

(Reindirizzamento Temporaneo)

Metodi e body non sono cambiati. La pagina web non è disponibile temporaneamente per ragioni non previste. Meglio del 302 quando operazioni che non usufruiscono del GET sono disponibili nel sito.

[2] La specificazione non intendeva permettere il cambiamenti nei metodi, ma ci sono degli user agents esistenti che cambiano i loro metodi. 307 è stato creato per rimuovere l'ambiguità del comportamento quando vengono usati metodi che non usufruiscono del GET.

Reindirizzamenti speciali

304 (Non modificato) reindirizza ad unapagina nella copia savata localmente nella cache (che non era vecchia), e 300 (Multiple Choice) è un reindirizzamento manuale: il body, presentato dal browser come una pagina web, lista i possibili reindirizzamenti e l'utente clicca su uno di essi per selezionarlo.

Codice Testo Casi d'uso tipici
300

Mutliple Choice

(Scelta Multipla)

Non molte: le scelte sono listate in una pagina HTML nel body. Scelte leggibili dalle macchine sono incentivate ad essere spedite come Link headers con rel=alternate.
304

Not Modified

(Non Modificata)

Inviata per rivalidate richieste condizionali. Indica che la risposta nella cache può essere ancora usata.

Modi alternativi per specificare un reindirizzamento

I reindirizzamenti HTTP non sono l'unico modo per definire dei reindirizzamenti. Ce ne sono infatti altri due:

  1. Reindirizzamenti HTML con l'elemento <meta>
  2. Reindirizzamenti di JavaScript tramite il DOM

Reindirizzamenti HTML

I reindirizzamenti HTML sono il modo migliore per creare reindirizzamenti, ma qualche volta non si ha il controllo sul server. In quel caso, prova a usare l'elemento <meta> con il suo attributo http-equiv impostato a  Refresh nel <head> della pagina. Quando viene mostrato sulla pagina, il browser andrà all'URL indicato.

<head>
  <meta http-equiv="Refresh" content="0; URL=https://example.com/">
</head>

L'attributo content dovrebbe iniziare con un numero indicando quanti secondi il browser dovrebbe aspettare prima di reindirizzare all'URL impostato. Impostarlo sempre a 0 per motivi di accessibilità.

Ovviamente questo metodo non funziona solo in HTML, e non può essere usato per immagini o altri tipi di contenuti.

Reindirizzamenti con JavaScript

Reindirizzamenti con JavaScript sono compiuti impostando una stringa dell'URL alla proprietà window.location, caricando la nuova pagina:

window.location = "https://example.com/";

Come i reindirizzamenti HTML, questo non funziona con tutte le risorse, e ovviamente, questo funzionerà solo con client che eseguono JavaScript. D'altro canto, ci sono più possibiltà: per esempio, si può causare il reindirizzamento solo se alcune condizioni sono rispettate.

Ordine di precedenza

Con tre modi per far causare i rendirizzamenti, molti modi possono essere usati allo stesso tempo. Ma quale è applicato per primo?

  1. I reindirizzamenti HTTP sono sempre eseguiti per primi — esisitono quando non c'è nemmeno una pagina trasmessa.
  2. I reindirizzamenti  HTML (<meta>) vengono eseguiti se non c'era nessun reindirizzamento HTTP.
  3. I reindirizzamenti con JavaScript sono eseguiti per ultimi, e solo se JavaScript è abilitato.

Quando possibile, usare reindirizzamenti HTTP e non aggiungere l'elemento di reindirizzamento <meta>. Se qualcuno cambia il reindirizzamento HTTP ma dimentica di cambiare il reindirizzamento HTML, il reindirizzamento non sarà più identico, il che potrebbe causare un loop infinito o altri incubi.

Casi d'uso

Ci sono molti casi d'uso per quanto riguarda i reindirizzamenti, ma le prestazioni sono intaccate da ogni reindirizzamento, il loro uso dovrebbe essere tenuto al minimo.

Aliasing dei domini

Idealmente c'è un posto, e di conseguenza un URL, per ogni risorsa. Ma ci sono ragioni per nomi alternativi per una risorsa:

Espandendo la portata del tuo sito
Un esempio comune è quando un sito risiede a www.example.com, ma accedendoci tramite example.com dovrebbe funzionare lo stesso. I reindirizzamenti da example.com a www.example.com sono preimpostati. Potresti anche reindirizzare da sinonimi comuni a frequenti refusi del tuo dominio.
Spostarsi ad un nuovo dominio
Per esempio, la tua compagnia è stata rinominata, ma vuoi che i link o i bookmark esistenti siano ancora in grado di trovarti sotto il tuo nuovo nome.
Forzando gli HTTPS
Richieste alla versione http:// del tuo sito, ti reindirizzeranno alla versione https:// di esso.

Quando i siti web vengono ristrutturati, gli URL cambiano. Anche se si aggiornano i link del sito facendoli combaciare con quelli dei nuovi URL, non si ha controllo sugli URL usati da risorse esterne.

Non si vogliono rompere questi link, visto che portano utenti preziosi e aiutano il SEO, quindi si impostano i reindirizzamenti dai vecchi URL a quelli nuovi..

Questa tenica funziona con i link interni alla pagina, ma si avvisa di non avere reindirizzamenti interni. Un reindirizzamento ha un costo sensibile a livello di prestazioni (visto che avviene una richiesta HTTP). Se si riesce a evitarlo correggiendo i link interni, sarebbe meglio correggere quei link.

Risposte temporanee a richieste non sicure

Le richeste Unsafe modificano lo stato del server e l'utente non dovrebbe reinviarle accidentalmente.

Di solito, non si vuole che gli utenti rimandino le richieste PUT, POSTDELETE. Se si fornisce la risposta come il risultato di questa richiesta, una semplice pressione del pulsante di ricarica rimanderà la richiesta (possibilmente dopo un messaggio di conferma).

In questo caso il server potrà rimandare indietro una riposta 303 (Vedi altro) per un URL contenente le informazioni corrette. Se il pulsante di ricarca viene premuto, solo quella pagina verrà rimostrata, senza rimandare le richieste non sicure.

Risposte temporanee a richieste lunghe

Alcune richieste potrebbero necessitare di più tempo sul server, per esempio le richieste DELETE che sono programmate per essere processate in seguito. In questo caso, la risposta sarà un reindirizzamento 303 (Vedi altro) che collegherà una pagina indicante che l'azione è stata programmata, ed eventualmente informerà del suo progresso, o permetterà di cancellarla.

Configurando reindirizzamenti in server comuni

Apache

I reindirizzamenti possono essere impostati sia che nel file di config del server che nell'.htaccess di ogni cartella.

Il modulo mod_alias ha direttive di Redirect e RedirectMatch che impostano i reindirizzamenti 302 di default:

<VirtualHost *:443>
	ServerName example.com
	Redirect / https://www.example.com
</VirtualHost>

L'URL https://example.com/ verrà reindirizzato a https://www.example.com/, come ogni file o cartella all'interno di esso (https://example.com/some-page verrà reindirizzato a https://www.example.com/some-page)

RedirectMatch non fa lo stesso, ma prende un regular expression per definire una collezione degli URL interessati:

RedirectMatch ^/images/(.*)$ https://images.example.com/$1

Tutti i documenti nella cartella images/ verranno reindirizzati a un dominio differente.

Se non si vuole un reindirizzamento temporaneo, un parametro extra (o il codice di stato HTTP da usare o la permanent keyword) possono essere usati per impostare un reindirizzamento differente:

Redirect permanent / https://www.example.com
# …acts the same as:
Redirect 301 / https://www.example.com

Anche il modulo mod_rewrite può creare reindirizzamenti. E' più flessibile, ma al contempo un po' più complesso.

Nginx

In Nginx, viene creato uno specifico blocco del server per il contenuto che si vuole reindirizzare:

server {
	listen 80;
	server_name example.com;
	return 301 $scheme://www.example.com$request_uri;
}

Per applicare un reindirizzamento ad una cartella o solo ad alcune pagine, usare la direttiva rewrite:

rewrite ^/images/(.*)$ https://images.example.com/$1 redirect;
rewrite ^/images/(.*)$ https://images.example.com/$1 permanent;

IIS

In IIS, vengono usate gli elementi <httpRedirect> per configurare i reindirizzamenti.

Loop di reindirizzamenti

I loop di reindirizzamenti succedono quando dei reindirizzamenti aggiuntivi seguono quello che è stato appena seguito. In altre parole, si crea un loop che non finirà mai e in cui nessuna pagina verrà mai trovata.

La maggior parte delle volte, questo è un problema lato server, e se il server non riesce a rilevarlo, manderà indietro un 500 Internal Server Error. Se si incontra un errore del genere subito dopo aver modificato la configurazione di un server, questo e molto probabile sia un loop di reindirizzamenti.

Qualche volta, il server non lo rileverà: un loop di reindirizzamenti può concernere diversi server, senza che nessuno di essi abbia  il quadro completo della situazione. In questo caso, i browser lo rileveranno e manderanno a schermo un messaggio di errore. Firefox manda:

Firefox has detected that the server is redirecting the request for this address in a way that will never complete

(Firefox ha rilevato che il server sta reindirizzando la richiesta per questo indirizzo in un modo che non si completerà mai)

…mentre Chrome manda:

This Webpage has a redirect loop

(Questa pagina web ha un loop di reindirizzamenti)

In entrambi i casi l'utente non potrà fare molto (a meno che una corruzione di qualche tipo non stia accadendo dal loro lato, come un'incompatiblità della cache o dei cookies).

E' importante evitare loop di reindirizzamenti, visto che romperebbero completamente quello che l'utente sperimentrà.