Eine URL in JavaScript zu kürzen bedeutet einen HTTP-POST. Sie senden den langen Link mit fetch an die API eines URL-Kürzers, übergeben Ihren API-Schlüssel als Bearer-Token und lesen den Kurzlink aus der JSON-Antwort. Seit Node 18 gibt es kein Paket zu installieren, denn fetch ist global verfügbar.
Entscheidend ist, wo dieser Code ausgeführt wird. Ein API-Schlüssel für einen URL-Kürzer ist ein Zugangsmittel mit Ausgabenrisiko, und clientseitiges JavaScript ist öffentlich, daher scheidet der Browser aus. Alles Folgende läuft serverseitig: ein Node-Skript, ein Route-Handler oder eine serverlose Funktion.
Dies ist die JavaScript-Version des allgemeinen Leitfadens zum Kürzen einer URL, der stattdessen das Dashboard und den Browser-Ablauf behandelt. Wenn Sie noch keinen Dienst ausgewählt haben, beschreibt der Überblick zur kostenlosen URL-Kürzer-API die Anfrageform, das Authentifizierungsmodell und die Limits des kostenlosen Tarifs, die dieser Artikel voraussetzt. Die Feldnamen unten stammen von Elido, aber das Muster, eine Ziel-URL per POST zu senden und eine Kurz-URL zurückzuerhalten, lässt sich auf die meisten modernen URL-Kürzer übertragen.
Der schnellste Weg: ein fetch-Aufruf in Node
Legen Sie den Schlüssel in einer Umgebungsvariable ab und senden Sie die Ziel-URL per POST an den Links-Endpunkt:
const res = await fetch("https://api.elido.app/v1/links", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ELIDO_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
destination_url: "https://example.com/spring-sale?utm_source=newsletter",
}),
signal: AbortSignal.timeout(10_000),
});
if (!res.ok) throw new Error(`shorten failed: ${res.status}`);
const { short_url } = await res.json();
console.log(short_url); // -> https://s.elido.me/ab12cd
Führen Sie das Ganze mit node --env-file=.env shorten.js aus. So gelangt der Schlüssel nie in den Quellcode.
Die Zeile if (!res.ok) ist keine Dekoration. fetch weist nur bei einem Netzwerkfehler oder Abbruch zurück. Eine 401 oder 500 kommt daher als vollständig aufgelöstes Promise mit ok: false zurück. Lassen Sie die Prüfung aus, sieht ein widerrufener Schlüssel genauso wie ein Erfolg aus, bis etwas nachgelagert versucht, undefined als Link zu verwenden. Wer von axios kommt, tappt hier einmal in die Falle.
Auch AbortSignal.timeout sollten Sie sich angewöhnen. Ohne diese Einstellung blockiert eine hängende Verbindung, bis der Socket von selbst stirbt. In einem Cronjob bedeutet das, dass der Job einfach verschwunden ist.
Warum der Browser der falsche Ort dafür ist
Sobald Sie das Snippet in eine React-Komponente einfügen, gehen zwei Dinge schief. Das erste ist CORS: Eine schlüsselautentifizierte API sendet für beliebige Websites keinen Access-Control-Allow-Origin-Header, daher blockiert der Browser die Antwort. Wer die CORS-Referenz von MDN liest, sucht danach meist nach einem Proxy, der den Fehler verschwinden lässt.
Der Fehler ist nur das Symptom. Das eigentliche Problem ist das zweite: Ein Schlüssel im Frontend-Code ist für jeden lesbar, der die DevTools öffnet oder das Bundle mit grep durchsucht. Bundler verstecken ihn nicht, Präfixe wie NEXT_PUBLIC_ weisen geradezu auf ihn hin, und ein öffentlicher Schlüssel für eine kostenpflichtige API ist ein kostenloses Kontingent für jemand anderen.
Das funktionierende Muster setzt eine eigene Route dazwischen. Der Browser sendet eine einfache URL an Ihren Endpunkt, Ihr Server fügt den Schlüssel hinzu, und der Schlüssel bleibt in einer Umgebungsvariable, die der Client nie sieht:
// app/api/shorten/route.js (Next.js App Router)
export async function POST(request) {
const { url } = await request.json();
const res = await fetch("https://api.elido.app/v1/links", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ELIDO_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ destination_url: url }),
});
const { short_url } = await res.json();
return Response.json({ short_url });
}
Validieren Sie url, bevor Sie sie weiterleiten. Ein offener Endpunkt, der alles kürzt, was jemand sendet, ist ein Open Redirect mit zusätzlichen Schritten. Der Beitrag zu Schwachstellen durch offene Weiterleitungen beschreibt, was Angreifer damit tun.
Timeout, Wiederholungsversuche und einen Idempotency-Key hinzufügen
Der Erfolgsfall umfasst acht Zeilen. Ein unbeaufsichtigter Job muss eine 429, einen vorübergehenden 5xx-Fehler und den unangenehmeren Fall überstehen, dass der POST erfolgreich ist, die Antwort aber nie eintrifft: Ihr Code läuft in ein Timeout, versucht es erneut und erzeugt nun zwei Kurzlinks für eine Ziel-URL.
Ein Idempotency-Key schließt diese Lücke. Erzeugen Sie pro URL einen Schlüssel, verwenden Sie ihn bei jedem Wiederholungsversuch für diese URL erneut, und die API gibt den ursprünglichen Link zurück, statt einen zweiten zu erstellen.
import { randomUUID } from "node:crypto";
const API = "https://api.elido.app/v1/links";
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
export async function shorten(destinationUrl, { retries = 3 } = {}) {
const idempotencyKey = randomUUID(); // one per URL, not per attempt
for (let attempt = 0; attempt < retries; attempt++) {
const res = await fetch(API, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ELIDO_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": idempotencyKey,
},
body: JSON.stringify({ destination_url: destinationUrl }),
signal: AbortSignal.timeout(10_000),
});
if (res.status === 429) {
await sleep(Number(res.headers.get("Retry-After") ?? 2) * 1000);
continue;
}
if (res.status >= 500) {
await sleep(2 ** attempt * 1000); // exponential backoff
continue;
}
if (!res.ok) {
throw new Error(`shorten failed: ${res.status} ${await res.text()}`);
}
return (await res.json()).short_url;
}
throw new Error(`shorten failed after ${retries} attempts`);
}
Eine 401 oder 403 wird sich niemals von selbst beheben. Diese Fehler werden daher sofort ausgelöst, statt drei Versuche zu verbrauchen. Eine 429 wartet genau so lange, wie es der Retry-After-Header verlangt. Nur bei 5xx-Fehlern kommt exponentielles Backoff zum Einsatz. Der ausführliche Beitrag zu Rate-Limits und Idempotenz erklärt, warum eine naive Wiederholungsschleife aus einem Ausfall eines Anbieters zwei macht.
Möchten Sie die Snippets unverändert ausführen? Erstellen Sie einen Schlüssel im kostenlosen Tarif, exportieren Sie ihn als ELIDO_API_KEY, und jedes Beispiel auf dieser Seite funktioniert unverändert.
URLs in großen Mengen kürzen, ohne das Rate-Limit auszulösen
Die naheliegende Bulk-Variante ist Promise.all(urls.map(shorten)). Sie startet jede Anfrage im selben Tick. Dadurch werden aus einer Liste mit 500 URLs 500 gleichzeitige Verbindungen, und die API beantwortet die meisten davon mit 429. Ein kleiner Pool löst das Problem: Eine feste Anzahl von Workern holt Elemente aus einer gemeinsamen Warteschlange, sodass die Nebenläufigkeit unabhängig von der Listenlänge konstant bleibt.
export async function shortenAll(urls, concurrency = 8) {
const queue = [...urls];
const results = new Map();
const worker = async () => {
while (queue.length) {
const url = queue.pop();
try {
results.set(url, await shorten(url));
} catch (err) {
results.set(url, `ERROR: ${err.message}`); // one bad URL must not sink the batch
}
}
};
await Promise.all(Array.from({ length: concurrency }, worker));
return results;
}
Wenn Sie die Ergebnisse anhand der ursprünglichen URL indizieren, bleibt ein teilweiser Fehler sichtbar und kann erneut ausgeführt werden, statt unbemerkt in der Ausgabe zu fehlen. Setzen Sie concurrency auf den Wert, den der Tarif dokumentiert. Acht ist ein sicherer Ausgangspunkt, und die Antwort-Header zeigen Ihnen, wann Sie den Wert senken sollten.
Wenn Sie all das lieber nicht selbst pflegen möchten, enthalten API und SDKs die Wiederholungs- und Pagination-Logik bereits. Der SDK-Schnellstart zeigt die typisierte Version desselben Aufrufs.
Wo der Code liegen sollte
Vier Orte decken fast alle Fälle ab. Ein einmaliges Skript, das eine CSV-Datei kürzt, läuft problemlos als reines Node mit --env-file. Ein Formular auf Ihrer Website benötigt den Route-Handler von oben. Dort bleibt der Schlüssel auf dem Server, und der Browser spricht nur mit Ihnen. Ein Queue-Worker passt zu einem ausreichend großen Batch, bei dem keine HTTP-Anfrage darauf warten sollte. Und ein Build-Schritt, der Kampagnenlinks erzeugt, gehört in CI, mit dem Schlüssel als Repository-Secret.
Ein Hinweis zu Edge-Runtimes: node:crypto ist dort nicht verfügbar, aber crypto.randomUUID() ist auf Vercel Edge, Cloudflare Workers und Deno ein globales Web-Crypto-Objekt. Tauschen Sie daher nur den Import aus, der Rest des Codes bleibt unverändert.
Der Ort ändert sich, die Checkliste nicht: Schlüssel in der Umgebung, ein Timeout für jede Anfrage, res.ok vor dem Body lesen und ein Idempotency-Key für alles, was zweimal laufen kann. Teams, die dies im großen Maßstab tun, lesen meist was die API noch bereitstellt, etwa Klicks, Tags und Ablaufdaten, und richten Webhooks für Link-Ereignisse ein, statt abzufragen.
Die Cornerstone-Serie lesen
Dieser Beitrag gehört zum Engineering-Cluster. Beginnen Sie mit dem Leitfaden zur kostenlosen URL-Kürzer-API für Endpunktform und Authentifizierung und lesen Sie danach den Beitrag zu Rate-Limits und Idempotenz, um sich unter Last korrekt zu verhalten. Die aktuelle Referenz finden Sie in der API-Dokumentation, und URL-Kürzer für Entwickler erklärt, worauf Sie bei einer API achten sollten, bevor Sie sich für eine entscheiden.
Verwandtes im Blog
- Eine URL in Python mit der requests-Bibliothek kürzen
- Eine URL in PHP mit curl, Guzzle und WordPress kürzen
- Eine URL in Go mit net/http kürzen
- Kostenlose URL-Kürzer-API: Anfrageform, Authentifizierung und Limits
- Eine URL in Java mit dem integrierten HttpClient kürzen
- Eine URL in C# mit HttpClient und .NET kürzen
Häufig gestellte Fragen
Wie kürze ich eine URL in JavaScript?
Senden Sie mit fetch einen HTTP-POST an die API eines URL-Kürzers. Übergeben Sie die lange URL im JSON-Body und Ihren API-Schlüssel als Bearer-Token und lesen Sie anschließend den Kurzlink aus der geparsten Antwort. In Node 18 oder neuer ist fetch bereits integriert, daher ist keine Paketinstallation erforderlich: Erstellen Sie die Header, senden Sie die Ziel-URL an den Links-Endpunkt und verwenden Sie das Feld short_url aus dem erhaltenen JSON.
Kann ich eine URL im Browser mit JavaScript kürzen?
Nicht mit Ihrem API-Schlüssel in der Seite. Alles in clientseitigem JavaScript ist in den DevTools lesbar. Ein an den Browser ausgelieferter Schlüssel ist daher ein öffentlicher Schlüssel, mit dem jeder Ihr Kontingent verbrauchen kann. Rufen Sie den URL-Kürzer stattdessen aus einer Server-Route oder einer serverlosen Funktion auf und lassen Sie den Browser diese Route aufrufen.
Warum gibt meine fetch-Anfrage an einen URL-Kürzer einen CORS-Fehler zurück?
Weil die API des URL-Kürzers für Ihre Website keinen Access-Control-Allow-Origin-Header sendet. Das ist bei einem schlüsselautentifizierten Endpunkt beabsichtigt. Der Browser blockiert die Antwort, auch wenn die Anfrage erfolgreich gewesen sein kann. Wenn Sie den Aufruf auf die Serverseite verlagern, verschwindet der Browser aus dem Pfad und der Fehler mit ihm.
Benötige ich ein npm-Paket, um URLs in Node.js zu kürzen?
Nein. Node stellt ab Version 18 ein globales fetch bereit, und ein API-Aufruf des URL-Kürzers besteht aus einem POST mit zwei Headern. Eine Abhängigkeit bringt Ihnen daher nur wenig. Verwenden Sie ein SDK, wenn Sie typisierte Antworten, integrierte Wiederholungsversuche und Pagination-Hilfsfunktionen über viele Endpunkte hinweg benötigen, statt nur für einen einzelnen Aufruf.
Wie kürze ich viele URLs gleichzeitig in Node.js?
Verwenden Sie einen kleinen Pool von Workern statt Promise.all für die gesamte Liste. So sind jederzeit nur wenige Anfragen gleichzeitig aktiv und Sie bleiben unter dem Rate-Limit. Senden Sie pro URL einen Idempotency-Key, damit eine wiederholte Anfrage den ursprünglichen Link zurückgibt, statt einen Duplikat-Link zu erstellen.
Löst fetch bei einer 401- oder 500-Antwort einen Fehler aus?
Nein, und das führt bei Umsteigern von axios oft zu Problemen. fetch weist nur eine Netzwerkfehler- oder abgebrochene Anfrage zurück. Eine 401 oder 500 kommt daher als aufgelöste Antwort mit ok gleich false an. Prüfen Sie response.ok selbst, bevor Sie den Body lesen, sonst sieht ein fehlgeschlagener Aufruf wie ein erfolgreicher aus.
Elido testen
URL einfügen, kurzer Link in Sekunden
Kein Konto nötig. Link bleibt 30 Tage aktiv. Konto erstellen, um ihn dauerhaft zu behalten.
Kostenlos, keine Anmeldung erforderlich · 2 pro Tag