Signatur
Beschreibung
Die schreibgeschützte Eigenschaft duplex eines Request-Objekts gibt an, wie Senden und Empfangen zeitlich zusammenhängen. Der einzige Wert, den die Fetch-Spezifikation derzeit festlegt, ist "half" (Halbduplex). Der Browser sendet dabei zuerst den kompletten Anfrage-Körper und verarbeitet erst danach die Antwort. Einen Vollduplex-Modus ("full") gibt es noch nicht. Er ist nur für die Zukunft vorgesehen.
Wichtig ist die Eigenschaft vor allem bei Streaming-Uploads. Wenn Sie fetch() oder new Request() einen ReadableStream als body übergeben, müssen Sie im Init-Objekt duplex: "half" angeben. Ohne diese Angabe werfen Chromium-Browser und Node.js (undici) einen TypeError. So kann später Vollduplex eingeführt werden, ohne dass sich das Verhalten bestehender Anwendungen stillschweigend ändert.
In der Praxis lesen Sie die Eigenschaft selten direkt. Häufiger nutzen Sie die Option duplex beim Erzeugen einer Anfrage. Außerdem können Sie mit einem Getter auf duplex prüfen, ob die Umgebung Streaming-Uploads überhaupt unterstützt (siehe Beispiel).
Rückgabewert
"half". In Umgebungen ohne diese Eigenschaft ist der Wert undefined.Beispiele
Duplex-Modus einer Anfrage auslesen
const request = new Request('https://example.com/upload', {
method: 'POST',
body: 'Hallo Welt'
});
// In Umgebungen ohne diese Eigenschaft ist der Wert undefined
console.log(request.duplex ?? 'nicht unterstützt');
Prüfen, ob Streaming-Uploads unterstützt werden
const supportsRequestStreams = (() => {
let duplexAccessed = false;
const hasContentType = new Request('https://example.com', {
method: 'POST',
body: new ReadableStream(),
// Der Getter wird nur aufgerufen, wenn der Browser die Option kennt
get duplex() {
duplexAccessed = true;
return 'half';
}
}).headers.has('Content-Type');
// Ohne Stream-Unterstützung wird der Stream zu "[object ReadableStream]"
// umgewandelt und Content-Type auf text/plain gesetzt
return duplexAccessed && !hasContentType;
})();
console.log('Streaming-Uploads:', supportsRequestStreams);
Daten als Stream hochladen (Browser)
const uploadLog = async (lines) => {
const encoder = new TextEncoderStream();
const writer = encoder.writable.getWriter();
// Daten Stück für Stück in den Stream schreiben
(async () => {
for (const line of lines) {
await writer.write(line + '\n');
}
await writer.close();
})();
const response = await fetch('/api/log', {
method: 'POST',
headers: { 'Content-Type': 'text/plain' },
body: encoder.readable,
duplex: 'half' // Pflicht, wenn body ein ReadableStream ist
});
return response.status;
};
console.log(await uploadLog(['Start', 'Schritt 1', 'Ende']));
Datei-Upload per Stream in Node.js
import { createReadStream } from 'node:fs';
import { Readable } from 'node:stream';
const body = Readable.toWeb(createReadStream('./backup.tar.gz'));
const response = await fetch('https://example.com/backup', {
method: 'PUT',
headers: { 'Content-Type': 'application/gzip' },
body,
duplex: 'half' // ohne diese Angabe: TypeError in Node.js 18+
});
console.log(response.ok);
// Wichtig · Fallstricke
- Pflicht bei Streams: Ist
bodyeinReadableStreamund fehltduplex: "half", werfen Chromium und Node.js einenTypeError. Bei Strings,Blob,FormDataoderArrayBufferist die Option nicht nötig. - Nur
"half"ist gültig: Der Wert"full"ist nur für die Zukunft vorgesehen und wird zurzeit abgelehnt. Die Antwort können Sie also erst lesen, wenn der Upload abgeschlossen ist. - Browser-Kompatibilität: Streaming-Uploads mit der Option
duplexgibt es in Chromium ab Version 105 und in Node.js ab Version 18. Firefox und Safari unterstützen Streaming-Uploads derzeit nicht. Die lesbare EigenschaftRequest.duplexselbst ist als experimentell eingestuft und fehlt in manchen Umgebungen (dann ist der Wertundefined). Prüfen Sie die Unterstützung zur Laufzeit, statt sie vorauszusetzen. - Weitere Einschränkungen in Chromium: Streaming-Uploads funktionieren nur über HTTP/2 oder HTTP/3; über HTTP/1.1 schlägt die Anfrage fehl. Außerdem gilt für Anfragen an andere Origins immer der CORS-Modus. Ein
ReadableStreamlässt sich nur einmal lesen, deshalb schlagen Weiterleitungen fehl, bei denen der Körper erneut gesendet werden müsste (alle außer 303). - In TypeScript fehlt
duplexje nach Version der Typdefinitionen noch inRequestInit. Dann hilft eine Typ-Erweiterung oder ein Cast.