Signatur
Beschreibung
Response.redirect() ist eine statische Fabrikmethode der Response-Schnittstelle. Sie erzeugt eine fertige HTTP-Umleitungsantwort: Der Statuscode wird auf einen der Umleitungscodes gesetzt (standardmäßig 302), und der Header Location enthält die angegebene URL. Einen Rumpf (Body) hat die Antwort nicht.
Gebraucht wird die Methode vor allem dort, wo JavaScript selbst Antworten erzeugt, also nicht nur empfängt: in Service Workern (im fetch-Event über event.respondWith()), in Edge-/Serverless-Umgebungen wie Cloudflare Workers, Deno Deploy, Vercel Edge Functions, und in Node.js-Frameworks, die auf der Fetch-API aufbauen (z. B. Hono, Remix, Next.js Route Handlers).
Relative URLs werden gegen die Basis-URL des aktuellen Kontexts aufgelöst, im Service Worker also gegen die Skript-URL. Die erzeugte Antwort hat unveränderliche Header (headers steht auf „immutable“). Wer zusätzliche Header braucht, etwa Set-Cookie oder Cache-Control, muss die Antwort mit new Response(null, { status, headers }) selbst bauen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $url Pflicht | string | URL | Ziel der Umleitung. Landet im Header Location. Relative Angaben werden gegen die Basis-URL der Umgebung aufgelöst. |
|
| $status | number | 302 | Optionaler Umleitungs-Statuscode. Erlaubt sind nur 301, 302, 303, 307 und 308. |
Rückgabewert
Response-Objekt mit dem gewählten Umleitungsstatus, dem Header Location und leerem Body. Die Header sind unveränderlich.Beispiele
Einfache Umleitung erzeugen und prüfen
const res = Response.redirect('https://example.com/neu', 301);
console.log(res.status);
console.log(res.headers.get('Location'));
console.log(res.body);
Service Worker: alte Pfade dauerhaft umleiten
// sw.js
const umleitungen = new Map([
['/blog/alt', '/artikel/neu'],
['/kontakt.html', '/kontakt']
]);
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
const ziel = umleitungen.get(url.pathname);
if (ziel && event.request.mode === 'navigate') {
// absolute URL bauen, damit der Ursprung eindeutig ist
event.respondWith(Response.redirect(new URL(ziel, url.origin), 301));
}
});
Edge-Worker: POST-Formular mit 303 zur Erfolgsseite
export default {
async fetch(request) {
const url = new URL(request.url);
if (request.method === 'POST' && url.pathname === '/bestellen') {
const daten = await request.formData();
console.log('Bestellung von', daten.get('email'));
// 303: Browser ruft das Ziel per GET ab (Post/Redirect/Get)
return Response.redirect(`${url.origin}/danke`, 303);
}
return new Response('Nicht gefunden', { status: 404 });
}
};
Ungültiger Statuscode wirft RangeError
try {
Response.redirect('https://example.com', 200);
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Erlaubte Statuscodes: Jeder andere Wert als
301,302,303,307oder308wirft einenRangeError. Eine ungültige URL wirft einenTypeError. - Die richtige Umleitungsart: Mit
301und302wandeln Browser ein POST oft in ein GET um.307und308behalten Methode und Body bei.303erzwingt GET. Außerdem werden301und308von Browsern aggressiv gecacht, deshalb dauerhafte Umleitungen vorher gut testen. - Unveränderliche Header:
res.headers.set()wirft auf dem Ergebnis einenTypeError. Für Cookies oder eigene Header stattdessen schreiben:new Response(null, { status: 302, headers: { Location: url, 'Set-Cookie': '…' } }). - Relative URLs: In Node.js und manchen Laufzeitumgebungen gibt es keine Basis-URL. Dort muss die URL absolut sein, sonst kommt ein
TypeError. Am sichersten ist immernew URL(pfad, request.url). - Sicherheit (Open Redirect): Die Ziel-URL niemals ungeprüft aus Query-Parametern übernehmen (z. B.
?next=). Sonst lassen sich Phishing-Umleitungen bauen. Erlaubte Ziele über eine Whitelist oder einen Ursprungsvergleich prüfen. - Service Worker: Wird eine Umleitungsantwort an eine Anfrage mit
redirect: 'manual'oder an bestimmte Nicht-Navigations-Anfragen übergeben, kann der Browser einen Netzwerkfehler melden. Umleitungen daher am besten aufrequest.mode === 'navigate'beschränken. - Kompatibilität: In allen aktuellen Browsern verfügbar, in Node.js global ab Version 18.