HTTP 300 Multiple Choices: come si gestisce

Cos'e HTTP 300 Multiple Choices

Il codice HTTP 300 Multiple Choices e un redirect informativo: il server segnala che la risorsa richiesta ha più rappresentazioni disponibili e il client deve scegliere quale ottenere. E un meccanismo di content negotiation alternativo a quello tramite header Accept-*, in cui la scelta avviene esplicitamente.

Quando viene emesso

Tipici scenari:

  • Una pagina disponibile in più lingue (it, en, fr) senza header Accept-Language affidabile.
  • Un documento offerto in più formati (HTML, PDF, JSON, XML).
  • Un'immagine in risoluzioni multiple.
  • Un video con codec alternativi.

Struttura della risposta

Il body della 300 non e standardizzato in modo stretto. Tipicamente contiene HTML con link cliccabili o JSON con la lista delle alternative:

HTTP/1.1 300 Multiple Choices
Content-Type: text/html
Location: /docs/it/manual.html

<html>
<body>
<h1>Scegli la lingua</h1>
<ul>
  <li><a href="/docs/it/manual.html">Italiano</a></li>
  <li><a href="/docs/en/manual.html">English</a></li>
</ul>
</body>
</html>

Header Location

Anche se non obbligatorio, il server puo includere Location: indicando la scelta "preferita" che il client puo seguire automaticamente. I browser tipicamente non seguono il redirect 300 da soli: mostrano la pagina con le scelte all'utente.

Negoziazione transparente vs reattiva

HTTP supporta due forme di content negotiation:

  • Server-driven (proactive): il server decide in base agli header Accept-*.
  • Client-driven (reactive): il server presenta opzioni con 300 e il client/utente sceglie.

Il 300 implementa il secondo modello, utile quando il server non puo decidere in modo affidabile (es. lingua sconosciuta).

Apache MultiViews

Apache supporta il 300 tramite il modulo mod_negotiation con la direttiva Options +MultiViews. Se richiedi /index ed esistono index.html.it e index.html.en, Apache:

  • Sceglie automaticamente in base a Accept-Language se possibile (servendo 200).
  • Restituisce 300 con elenco varianti se la scelta e ambigua.

Header Alternates (obsoleto)

Le vecchie specifiche prevedevano un'header Alternates: per descrivere le varianti in modo strutturato. Oggi e deprecato: si preferisce il body HTML o un payload JSON in API REST.

Adozione e SEO

Il 300 e raro nel web moderno. Le ragioni:

  • I motori di ricerca non lo gestiscono bene: meglio una landing page con 200 e link interni.
  • Browser non eseguono auto-redirect: l'utente vede un menu che puo confondere.
  • Content negotiation server-side (Accept-Language) e generalmente sufficiente.

Gestione lato client

In una SPA o API custom, intercetta il 300 con il tuo fetch wrapper:

const res = await fetch('/api/resource');
if (res.status === 300) {
  const options = await res.json();
  // mostra UI di scelta all'utente
}

Best practice

Usa il 300 solo quando la scelta richiede davvero intervento umano. Per la maggior parte dei casi, una redirect 302/307 verso la rappresentazione corretta tramite content negotiation server-side e più semplice e SEO-friendly. Il 300 resta una soluzione elegante per documentazione tecnica multilingua o portali multi-formato dove l'utente vuole scegliere consapevolmente.

Storia del codice

Il 300 nasce con HTTP/1.0 (RFC 1945) per gestire scenari in cui il server vuole dare scelta al client. Negli anni '90 era più comune: documentazione tecnica in più lingue, mirror geografici diversi, alternative di codifica. Con l'arrivo di HTTP/1.1 e meccanismi più sofisticati di content negotiation server-driven, il 300 e diventato sempre più raro.

Esempio Apache MultiViews completo

<Directory /var/www/docs>
    Options +MultiViews
    LanguagePriority it en fr
    ForceLanguagePriority Prefer Fallback
</Directory>

Con questa configurazione, Apache tenta prima la lingua dell'header Accept-Language. Se ambigua, emette 300 con la lista. ForceLanguagePriority Prefer evita il 300 forzando una scelta default.

300 in protocolli moderni

Nel mondo delle API REST attuali, il 300 e essenzialmente sostituito da altri pattern: discovery endpoint che ritornano la lista delle varianti (JSON), HATEOAS con link verso ogni rappresentazione, oppure header personalizzati. Il vantaggio del 300 e che e standard HTTP: ogni client lo riconosce come "scegli tra le opzioni".

Body JSON moderno

HTTP/1.1 300 Multiple Choices
Content-Type: application/json

{
  "options": [
    {"format": "json", "url": "/api/data.json"},
    {"format": "xml", "url": "/api/data.xml"},
    {"format": "csv", "url": "/api/data.csv"}
  ]
}

Mirror geografici

Negli anni '90, molti download (es. ISO Linux, software open-source) usavano il 300 per presentare la lista di mirror geografici. L'utente sceglieva quello geograficamente più vicino. Oggi questo e gestito da geo-DNS, anycast e CDN, ma il pattern 300 resta sintatticamente corretto.

API REST e content negotiation

API REST moderne usano raramente il 300: preferiscono Accept-Encoding/Accept e content negotiation server-side. Il 300 emerge ancora in scenari edge case: documentazione API che offre formati multipli (JSON, YAML, XML) e vuole esporre la scelta esplicitamente.

Test di compatibilità

Browser test: aprire una URL che restituisce 300 mostra normalmente la pagina HTML del body. Chrome non auto-redireziona via Location del 300. Curl con -L segue il primo Location ma stampa warning. Tool come Postman mostrano il body così com'e.

Edge case: 300 senza Location

Lo standard non rende Location obbligatorio nel 300, ma e fortemente raccomandato. Un 300 senza Location forza il client a parsare il body per decidere, riducendo l'utilita semantica del codice.

Hai bisogno di aiuto?

Se il tuo sito mostra errori HTTP, il team di G Tech Group puo aiutarti. Contattaci tramite il modulo di contatto.

Hai trovato utile quest'articolo?