Node: Implementieren Sie window.fetch in den Kern

Erstellt am 16. März 2018  ·  158Kommentare  ·  Quelle: nodejs/node

https://github.com/bitinn/node-fetch

Es wäre sinnvoll, wenn window.fetch in den Kern implementiert würde. Es scheint eine ausreichend stabile API zu sein, die ein guter Kandidat für die Aufnahme wäre. Ich bin mir nicht sicher, wie der Prozess von hier aus ist, dachte aber, ich würde ein Problem ansprechen :)

feature request http http2

Hilfreichster Kommentar

Dies wäre definitiv in einfachen plattformübergreifenden APIs nützlich, und ich denke, dafür verwenden viele Leute bereits Node-Fetch. Es wäre auch schön, wenn die HTTP/1-v-HTTP/2-Aushandlung automatisch wie in Browsern gehandhabt werden könnte.

Alle 158 Kommentare

Dies ist von Zeit zu Zeit aufgetaucht, hat aber noch nicht viel Anklang gefunden. Mal sehen, was die Leute denken :-)

Bradley und ich haben dies auf Umwegen zum Thema import von URLs diskutiert. Wenn diese Funktion eingeführt wurde (und ich denke, im Allgemeinen wollen wir sie), müssten wir Folgendes implementieren: https://html.spec.whatwg.org/multipage/webappapis.html#fetch -a-single-module-script die die Abrufspezifikation verwendet. Als weitere Anmerkung, wenn dies im Kern hinzugefügt wurde, würde ich eine vorhandene C++-Implementierung von einem der Browser einziehen wollen. Als absolutes Minimum wird der Knoten jedoch definitiv Request - und Response -Objekte hinzufügen, er fügt möglicherweise nur keine Funktion namens fetch hinzu

-1 Diese Art von Funktionalität auf höherer Ebene wird am besten dem Userland überlassen

Dies wäre definitiv in einfachen plattformübergreifenden APIs nützlich, und ich denke, dafür verwenden viele Leute bereits Node-Fetch. Es wäre auch schön, wenn die HTTP/1-v-HTTP/2-Aushandlung automatisch wie in Browsern gehandhabt werden könnte.

Ich würde das lieben! ❤️

Isomorphes JS ist einer der Hauptgründe, warum Leute, die mit JS am Frontend beginnen, schließlich zu Node.js am Backend greifen.

Sie können genau dieselbe Funktion im Browser und auf dem Server ausführen, und der einzige Streitpunkt, den ich immer wieder finde, ist window.fetch.

Ein Teil des Codes, der auf dem Server und dem Client ausgeführt wird, muss HTTP-Anforderungen an einen anderen Server senden (denken Sie an Microservices mit serverseitigem und clientseitigem Rendering).

Ein Grund dafür, es in den Kern zu bringen, ist, dass das Erstellen von HTTP-Anforderungen (Client) eng mit der Beantwortung von HTTP-Anforderungen (Server) verbunden ist.

Und wir haben jetzt isomorphes URL-Parsing, also müssen wir jetzt nur noch holen! Lassen Sie uns das Abrufen möglich machen!

Fetch ist laut seinem Autor und Hauptunterstützer "Low-Level", daher fehlen eine Reihe von Funktionen wie Unterstützung für Inhaltstypen, JSON ist nicht Standard, keine Kodierung von Abfragezeichenfolgen. Apps, die einen hochwertigen HTTP-Client benötigen, der in allen JavaScript-Umgebungen verfügbar ist, können Superagent weiterhin verwenden.

@mikemaccana der Abruf, über den wir sprechen, ist https://fetch.spec.whatwg.org/ und ich denke nicht, dass es angebracht ist, andere http-Bibliotheken einzustecken

@devsnek Ja, ich weiß, darauf habe ich mich speziell bezogen. Ich habe keine besondere Freude an Superagent, abgesehen davon, dass es Folgendes ist:

  • ein voll funktionsfähiger HTTP-Client
  • im Knoten und im Browser verfügbar
  • beliebter als holen
  • hat standardmäßig JSON
  • codiert Abfragezeichenfolgen
  • verwendet Inhaltstypen, um den Antworttext zu bestimmen
  • verwendet HTTP-Verben als Methodennamen, sodass Sie problemlos .get() - und .post() -Dinge verwenden können, anstatt mit der Methode POST abzurufen, was ein etwas seltsames mentales Modell ist

Wenn fetch diese unterstützt, würde ich vorschlagen, dass sie in node. Um es noch einmal zu wiederholen: Ich habe den Autor und Hauptbefürworter von fetch, Jake Archibald, gefragt, warum es diese Dinge nicht unterstützt, und es heißt, dass fetch als Low-Level-API konzipiert ist und Dinge wie vernünftige Standardwerte von höherer Ebene hinzugefügt werden können/sollten APIs. Daher sehe ich keinen Grund, Fetch im Knoten oder im Browser zu verwenden.

@mikemaccana

Dies sind eigentlich wünschenswerte Eigenschaften für das Argument, Fetch in den Node.js-Kern aufzunehmen, wenn wir den Kern niedrig und klein halten wollen. Ich glaube, wir müssen irgendwann sowieso eine versprochene API für http/http2 bereitstellen und als vorhandene Spezifikation für einen ähnlichen Satz von Low-Level-Funktionen wie unser http abrufen, was eine Überlegung wert ist. Meiner Erfahrung nach fühlen sich die fehlenden Teile in fetch den fehlenden Teilen in http von Node.js ziemlich ähnlich, der Hauptunterschied besteht darin, dass Sie eine spezifizierte API haben, auf die Sie sich verlassen können.

Ich bezweifle auch irgendwie den Teil "beliebter als Fetch". Ich glaube nicht, dass es so viele Leute gibt, die Super-Agent im Browser verwenden wie in Node, da Fetch einfach im Browser vorhanden ist (Modulo-Situationen, die Polyfills erfordern)?

Obwohl ich glaube, dass wir, bevor wir mit der Implementierung von Fetch beginnen, die Stream-API im Browser einführen müssen ? Steht die Einführung eines weiteren Streams in Node.js auf dem Tisch?

Das einzige Mal, dass ich gezwungen war, im Browser auf XHR zurückzugreifen, war, als ich Fortschritte brauchte, obwohl ich denke, dass es mit den ReadableStreams des Browsers möglich ist, dasselbe mit einer etwas umständlichen API zu tun ( res.body.read().byteLength ). - Wenn ich den Fortschritt in Node.js implementieren würde, muss ich wohl chunk.byteLength aus dem Chunk verwenden, der im data -Ereignis ausgegeben wird, wo der Unterschied zwischen den beiden Streams beginnt von Bedeutung sein.

Außerdem scheint die Abrufspezifikation derzeit (noch?) keine Zeitüberschreitung oder Agenten zu enthalten, es könnten im Vergleich zu unserer bestehenden HTTP-API weitere Funktionen fehlen. Als Referenz scheint node-fetch diese nicht standardmäßigen Optionen zu implementieren. Auch hier sind wir uns nicht sicher, ob unsere Implementierung nicht standardmäßige Funktionalitäten implementieren sollte, selbst wenn sie die fehlenden Teile im Vergleich zur alten API liefern.

auch cc @TimothyGu Sie könnten interessiert sein?

@thecodingdude

stimme überhaupt nicht zu; Node verwendet v8 und sollte daher so viele v8-Funktionen wie möglich implementieren, die sinnvoll sind. fetch ist eine von denen, bei denen Entwickler keine npm-Installationsanforderung oder Node-Fetch benötigen, die sehr beliebte Bibliotheken sind, sodass diese Funktionalität im Kern enthalten sein muss.

Technisch gesehen ist Abrufen jedoch keine v8-Funktion, sondern eine von WHATWG spezifizierte API, während v8 ECMA-262 implementiert, eine Spezifikation von ECMA TC39. Wenn v8 Abrufen implementiert, gäbe es diese Funktionsanforderung nicht, da wir im Grunde nur was offenlegen v8 ausgesetzt.

Übrigens: Ich glaube nicht, dass wir darüber sprechen, npm-Pakete in den Kern zu ziehen? Vielmehr sprechen wir davon, die Spezifikation selbst zu implementieren und die WPT einzubinden , um die Konformität zu testen, möglicherweise mit einer Reihe von in C++ geschriebenem Code, ähnlich wie wir es für WHATWG URL getan haben.

@thecodingdude Die anhaltende Popularität von Non-Fetch-Bibliotheken ist keine persönliche Meinung, sondern eine Tatsache - Superagent hatte diese Woche 1,6 Millionen Downloads . Ebensowenig das Fehlen vernünftiger High-Level-Defaults in fetch: das wird wiederum (wieder) vom Autor von fetch anerkannt. Bitte stellen Sie überprüfbare objektive technische Fakten nicht in irrelevante subjektive Meinungen um, weil Sie sie nicht mögen.

Bitte schließen Sie hier keine anderen Bibliotheken an, sie sind für unsere Diskussion irrelevant.

Entwickler müssten keine npm-Installationsanforderung oder Node-Fetch ausführen

😂👍

Ich persönlich bin aus zwei Gründen -1:

  1. Zwei verschiedene APIs ( fetch() und http.request() ) zu haben, um dasselbe zu tun, ist unzusammenhängend.

  2. fetch() ist nicht flexibel genug, um Dinge wie Proxying, benutzerdefinierte TLS-Zertifikate usw. zu unterstützen. Es wird vom Browser transparent gehandhabt, aber das funktioniert nicht in node.js.

derzeit stimmen 84 Personen zu

Darauf würde ich nicht zu viel Wert legen. GH-Umfragen lassen sich leicht durch Twitter-Brigade und so weiter spielen. Ich würde sie ernster nehmen, wenn es einen Dollar kosten würde, eine positive Stimme abzugeben.

thecodingdude Ich habe mit einer stichpunktartigen Liste von technischen Gründen kommentiert, warum fetch als Allzweck-HTTP-Client ungeeignet ist. Ich bin mir bewusst, dass es Ihnen "egal ist, wie / gut schlecht geholt wird". Ich denke, das ist falsch: Der Knoten sollte hochwertige APIs auswählen und übernehmen. Dass Sie persönlich nicht an der Qualität von Fetch interessiert sind, macht es für die Diskussion nicht irrelevant. Die Browserhersteller haben fetch mit window.xhr verglichen, node ist es nicht.

@mikemaccana Warum muss fetch High-Level-Funktionen wie "HTTP-Verben als Methodennamen" haben, damit es in den Kern aufgenommen werden kann? Sie können trivialerweise Ihre eigenen Methoden schreiben, die dies zusätzlich zu den anderen von Ihnen erwähnten High-Level-Funktionen tun.

Das Schöne daran, Standard-APIs zu haben, die sowohl vom Browser als auch von Node gemeinsam genutzt werden, ist, dass Sie viel einfacher konsistentes Verhalten erzielen können, wenn Sie die High-Level-API so schreiben, dass sie auf die Low-Level-API abzielt (in diesem Fall fetch ). Sie müssen Ihre API dazu bringen, Unterschiede zwischen verschiedenen APIs im Knoten und im Browser zu umgehen.

@thecodingdude irgendein Grund, warum dies geschlossen wurde? Diskussion scheint noch in Bewegung zu sein

@devsnek Ja, ich bin nicht zufrieden mit der Art und Weise, wie diese Diskussion und dieses Problem verlaufen sind, und mir ist klar, dass Github-Probleme einfach nicht das geeignete Forum sind, um zu diskutieren, ob Funktionen im Kern landen sollten. Ich bevorzuge die Node-Eps , da dies ein richtiges Dokument war, in dem der Vorschlag skizziert wurde. Meine Absicht war es, die Gedanken des Kernteams und aller anderen Personen zu sammeln, die an der Zusammenführung von Funktionen in den Kern beteiligt sind (Planung, Codierung, Test usw.). Stattdessen ist die Diskussion hier bisher im Grunde sinnlos. Es sollte um die Machbarkeit gehen, was erforderlich wäre und wann ein solches Feature zusammengeführt werden könnte.

Schauen Sie sich diese Ausgabe an und versuchen Sie, der Diskussionslawine über Websockets im Kern zu folgen. Es gibt zu viel Lärm und keinen einfachen Ansatz, um neue Funktionen vorzuschlagen. Ich denke, das RFC -System von PHP ist ein gutes Beispiel für das Hinzufügen neuer Funktionen. Klar, prägnant, rechenschaftspflichtig.

Ich bin bereit, einen _rfc_ und seine Vorzüge in einer separaten Ausgabe zu diskutieren, aber es ist klar, dass dies nirgendwohin führt, mit wenig bis gar keiner Interaktion von TSC oder irgendjemandem, der wichtig ist, also macht es keinen Sinn, es einfach so zu lassen, die Posteingänge der Leute zu spammen.

Ich werde davon absehen, solche Probleme in Zukunft zu machen, mein Fehler.
cc @Jasnell

@Jamesernator Warum muss fetch hochrangige Funktionen wie "HTTP-Verben als Methodennamen" haben, damit es in den Kern aufgenommen werden kann? Sie können trivialerweise Ihre eigenen Methoden schreiben, die dies zusätzlich zu den anderen von Ihnen erwähnten High-Level-Funktionen tun

Sicher. Ich und alle anderen, die Abfragezeichenfolgen verwenden müssen, können eine Methode zum Codieren von Abfragezeichenfolgen schreiben. Besser noch: Lassen Sie uns einen HTTP-Client von guter Qualität mit Batterien in den Knoten einbauen, wo ihn nicht jeder reparieren muss.

@thecodingdude sieht aus, als hättest du deinen Kommentar gelöscht, aber um trotzdem zu antworten: HTTP2 ist notwendig, weil es erforderlich ist, die aktuelle Version von HTTP zu sprechen. fetch ist nicht notwendig, weil es nur einer von vielen HTTP-Clients ist, und aus den genannten Gründen kein sehr guter.

@mikemaccana Aber der Grund für die Aufnahme von fetch in Node Core liegt nicht in den enthaltenen Batterien, sondern darin, dass Sie Code schreiben können, der sowohl auf den Browser als auch auf Node gleichzeitig abzielt. Aus diesem Grund unterstützt Node auch den URL -Konstruktor (und er ist jetzt sogar global wie im Browser in Knoten 10) und die Dokumentation verweist sogar auf die alten url.Url -Objekte als Legacy-URL-API .

Dies ist eine gute Sache, da es bedeutet, dass einige Module, die beispielsweise dynamischen Import verwenden, keine Bibliothek enthalten müssen, um Ressourcen relativ dazu laden zu können, z.

...

export default async function isWordForLanguage(language="english") {
    const wordDataUrl = new URL(`./resources/${ language }.csv`, import.meta.url)
    const words = await loadSomehow(wordDataUrl)
    return makeIsWord(words)
}

Jetzt hat dieser Code kein plattformspezifisches Verhalten (unter der Annahme einer loadSomehow Methode, die möglicherweise fetch sein könnte). Die Vorteile sollten ziemlich offensichtlich sein:

  • Die Verwendung von APIs, die standardisiert und sowohl im Browser als auch in Node enthalten sind, bedeutet, dass Sie in beiden Kontexten Unterstützung erhalten, wenn es Probleme mit Implementierungen gibt (und daher keine Chance auf tote oder veraltete Bibliotheken).
  • Kleinere Bibliotheken für Funktionen auf hoher Ebene, da sie keine Plattformunterschiede ausgleichen müssen, sie verwenden einfach die universelle API ( URL oder fetch oder was auch immer) und bauen direkt darauf auf
  • Das Gleiche gilt für Ihre eigenen Bibliotheken, die Verhalten auf hoher Ebene benötigen

Ich denke, es ist ein sinnloses Unterfangen, eine weitere http -Bibliothek in Node zu erstellen, wenn dies nicht der Interoperabilität dient. Wenn Node einen anderen erstellt, der sich nicht im Browser befindet, erhalten Sie einfach die gleiche Situation wie jetzt. Wenn Sie Browser-interoperablen Code wünschen, bauen Sie eine weitere Bibliothek darauf auf, nur um die Interoperabilität mit Browsern zu erhalten.

Wenn Sie der Meinung sind, dass es für Browser wichtig ist, High-Level-APIs standardmäßig zu unterstützen, dann lohnt es sich wahrscheinlich, die Bemühungen zu unterstützen, High-Level-APIs zu einem Teil des Browsers zu machen und Ihre Ziele klar zu machen, was Sie von High-Level-APIs erwarten. Ich bin sicher, viele Entwickler würden es begrüßen, API-Spezifikationen auf hoher Ebene zu erhalten.

Noch besser wäre es, wenn es eine Möglichkeit gäbe, Node und Browser dazu zu bringen, an High-Level-Funktionen zusammenzuarbeiten. Ich bin mir nicht sicher, wie das funktionieren könnte, aber wenn es möglich wäre, wäre es viel einfacher, High-Level-Funktionen vorzuschlagen APIs, die auf alle Umgebungen abzielen, anstatt in Node oder den Browsern isoliert zu sein.

Danke @Jamesernator - es ist schön zu wissen, dass es Bemühungen gibt, dies in größerem Umfang zu lösen. Danke auch, dass du höflich bist und meine Kommentare tatsächlich liest, bevor du antwortest.

Ich neige zu der Annahme, dass, wenn NodeJS heute entwickelt worden wäre, fetch zweifellos im Namen der Anpassung an Browser-APIs implementiert worden wäre. Ja, es gibt einige wirklich interessante Grenzfälle, aber @TimothyGu hat diese wirklich gut in der Node-Fetch-Integration gehandhabt.

@thecodingdude stört es dich, wenn ich wieder öffne? Wir könnten hier möglicherweise noch Dinge anstehen - ich glaube, die ausführliche Diskussion ist noch nicht ganz ausgereift, und ich denke, es gibt persönlich noch fruchtbare Diskussionen zu führen.

@bnoordhuis node-fetch handhabt hier die Unterschiede, indem es die NodeJS-spezifische Option agent unterstützt, die Funktionen wie Proxy https://github.com/bitinn/node-fetch#options delegiert. Es bricht die universelle API, könnte aber auch ziemlich einfach bedingt gemacht werden, also neige ich dazu zu denken, dass es ein ziemlich guter Kompromiss mit diesem Zeug zu sein scheint. Es könnte auch entschieden werden, dass eine solche Abweichung ebenfalls eine schlechte Idee ist, wenn auch sicherlich.

Das Wichtigste ist jedoch, dass diese Abruf-API absichtlich eingeschränkt ist - HTTP- und HTTP/2-APIs bleiben immer noch grundlegend, dies könnte nur die einfache universelle Erfahrung bieten. Es ist nichts falsch daran, zwei APIs zu haben, die dasselbe tun, wenn eine auf der anderen aufbaut, um eine überzeugende Benutzererfahrung zu bieten.

@guybedford Fühlen Sie sich frei, eine neue Ausgabe zu erstellen, in der dies weiter diskutiert wird, wenn dies die am besten geeignete Richtung ist. Ich würde technische Diskussionen über die Implementierung selbst viel bevorzugen und nicht, was fetch im Vergleich zu Alternativen tut / nicht tut, weshalb ich das Problem überhaupt geschlossen habe.

Ganz ehrlich, ich sehe nicht ein, warum diese Diskussion auf github stattfinden muss - zumindest sollte sie für Mitarbeiter gesperrt sein, die am Code arbeiten, und Diskussionen, die sich ausschließlich auf die Implementierung von Fetch konzentrieren, identisch mit dem Browser, wo möglich, und nicht mehr und nicht weniger.

@thecodingdude Ich bin mir immer noch nicht ganz sicher, warum ich hier eine neue Ausgabe brauche. Die Diskussion der Problemgrenzen sollte sicherlich der erste Schritt für jedes neue Feature sein, und es sollte auch eine breitere Diskussion zu Beginn berücksichtigt werden. 16 Kommentare scheinen auch kaum aus der Spur zu sein.

Sicherlich sind die technischen Einzelheiten, ob es JS oder C++ sein soll, oder wo die Grenze zu Pooling und Proxys gezogen werden soll, wichtig, aber die Dinge müssen ihren eigenen Lauf nehmen.

Es ist nichts falsch daran, zwei APIs zu haben, die dasselbe tun, wenn eine auf der anderen aufbaut, um eine überzeugende Benutzererfahrung zu bieten.

Aber es ist nicht "auf" - sie machen dasselbe, nur mit unterschiedlichen Schnittstellen.

Argumente für fetch() laufen auf „Bequemlichkeit“ hinaus – kein guter Grund für die Aufnahme in den Kern.

Danke @bnoordhuis, dies sind wichtige Punkte, wo sich die Leitung in Node befindet, und ich muss zugeben, dass ich mit dieser Art von Diskussionen historisch nicht vertraut bin, aber solange Node bestrebt ist, Kerndienstprogramme bereitzustellen, scheint dies ein wichtiger Punkt zu sein gehören zu mir.

Aber es ist nicht "auf" - sie machen dasselbe, nur mit unterschiedlichen Schnittstellen.

Derzeit baut Node-Fetch auf dem http-Modul auf, ich persönlich würde hier eine solche JS-basierte Implementierung bevorzugen, die genau mit dem arbeitet, was @TimothyGu bereits als eine der beliebtesten Bibliotheken erstellt hat. Das Muster, APIs auf hoher und niedriger Ebene für dasselbe zu haben, ist etabliert.

Argumente für fetch() laufen auf „Bequemlichkeit“ hinaus – kein guter Grund für die Aufnahme in core.

Komfort ist ein enorm wichtiges Argument, die Frage ist, wie hoch die Wartungskosten sind. Node unterstützt nicht nur Module und native Bindungen, sondern stellt gegebenenfalls Serverdienstprogramme und universelle APIs bereit. Wie ich schon sagte, scheint mir fetch heutzutage ein kritischer Teil der universellen Werkzeugkiste zu sein.

Ich würde sogar darauf drängen, dass fetch in Zukunft HTTP/2 transparent integriert, sodass eine solche Funktion nicht nur auf den vorhandenen integrierten Funktionen aufbauen kann, sondern auch eine Vereinheitlichung bietet, die wir derzeit nicht haben. Ich weiß, dass hier Komplexitäten angegangen werden müssen, und es ist keine Selbstverständlichkeit, aber es fühlt sich an, als wäre es ein großer Gewinn für Node und seine Benutzer.

Derzeit baut node-fetch auf dem http-Modul auf

Das ist ein Implementierungsdetail. Betrachtet man es aus der Perspektive eines Benutzers, gibt es verschiedene Möglichkeiten, dasselbe zu tun, und keine ist eindeutig überlegen.

Komfort ist ein enorm wichtiges Argument, die Frage ist, wie hoch die Wartungskosten sind.

Die öffentliche Schnittstelle von eingebauten Modulen kann nicht einfach geändert werden, manchmal überhaupt nicht. Im besten Fall ist es immer noch eine jahrelange Angelegenheit. Module auf npm haben dieses Problem nicht.

fetch() spricht dafür, dass es ein Standard ist, außer dass wir es erweitern müssten, um es nutzbar zu machen (z. B. die agent -Option, die Sie erwähnt haben).

Es scheint, als müssten wir prüfen, ob der beim Node-Fetch verwendete agent -Ansatz geeignet wäre und als wie stabil diese API oder eine andere ähnliche API angesehen werden könnte. Vielleicht kann @TimothyGu Gedanken zur Stabilität dieser Fälle teilen, um standardmäßig eine Abwärtskompatibilität sicherzustellen.

Ich bin in dieser Frage zwiegespalten. Als beständiger Befürworter des kleinen Kerns weise ich auf die Flexibilität hin, Breaking Changes vorzunehmen, die ein Userland-Modul ermöglicht. Allerdings war Node-Fetch (und die Fetch-API) bemerkenswert stabil: Node-Fetch hatte in den letzten Jahren nur eine bahnbrechende Version , und die derzeit geplanten Breaking Changes sind alle logistisch (die unterstützten Versionen von Node.js und a Paket von Drittanbietern).

Andererseits glaube ich, dass es für Benutzer eine viel bessere Erfahrung wäre, wenn sie kein Paket für den sehr einfachen Zweck des Abrufens einer Datei in einem Skript installieren müssten, mit einer Schnittstelle, mit der sie vertraut sein könnten. Nein, http.request zählt nicht als eine Lösung, da man mehr Arbeit in die Unterstützung von Umleitungen, Komprimierung und jetzt transparentem HTTP/2 stecken müsste.

In Bezug auf die von @bnoordhuis erwähnte Funktionslücke:

fetch() spricht dafür, dass es sich um einen Standard handelt, außer dass wir es erweitern müssten, um es nutzbar zu machen (z. B. die von Ihnen erwähnte agent -Option).

Wenn node-fetch alle seine Erweiterungen (grep für "node-fetch extension" in der README ) entfernt hätte, wäre es meiner Meinung nach immer noch ein absolut nützliches Tool, insbesondere für Einzeldatei-Skripte. Sagen Sie dem Benutzer: „ fetch() wird nur der Bequemlichkeit halber angeboten, und für weitere Funktionen/Anpassungen (wie die Option agent ), verwenden Sie node-fetch/request/etc.“ ist eine absolut brauchbare Lösung.

Am Ende würde ich mich freuen, wenn fetch() und periphere APIs Teil des Kerns werden.

Damit der Knoten Fetch unterstützt, müssen wir möglicherweise ein paar Spezifikationsänderungen vornehmen, damit er Dinge wie CORS umgehen kann, aber es klingt machbar.

Ich denke jedoch nicht, dass es eine Überlegung wert ist, es sei denn/bis der Knoten https://streams.spec.whatwg.org/ implementiert, was ich gerne sehen würde! Bearbeiten: Obwohl Browser versandt wurden, bevor Streams gelandet sind, könnte Node das Gleiche tun.

@mikemaccana

Fetch ist laut seinem Autor "Low-Level".

Es ist Low-Level für das Web. Aber in gewisser Weise macht es das aufgrund seiner relativ lockeren Sicherheitsanforderungen zu einem hohen Niveau für Knoten. Obwohl dies ziemlich einfach in der Spezifikation angeheftet werden könnte.

und Hauptunterstützer, daher fehlen eine Reihe von Funktionen wie die Unterstützung für Inhaltstypen

Fetch unterstützt den Header Content-Type .

JSON ist nicht Standard

Wofür? Antwortstellen? Einen Typ zu haben, der sich abhängig von einem Header des Absenders ändert, klingt für mich riskant. Beispielsweise könnten Sie leicht mit Code enden, der großartig funktioniert, wenn die Antwort als Objekt herausspringt, aber wenn ein Angreifer Header manipulieren könnte, um diese in ein binäres Format umzuwandeln, könnten schlimme Dinge passieren.

keine Codierung der Abfragezeichenfolge

Das ist nicht wahr. Die Abruf-API unterstützt URL-Objekte, die searchParams unterstützen: https://url.spec.whatwg.org/#interface -urlsearchparams. Diese können auch als Anforderungstexte verwendet werden.

'Abrufen mit der Methode POST', was ein etwas seltsames mentales Modell ist

So funktioniert HTTP. Der Methodenname ist eine Zeichenfolge.

Ich habe den Autor und Hauptbefürworter von fetch, Jake Archibald, gefragt

Ich bin nicht der Autor von fetch, obwohl ich einen Beitrag geleistet habe. Ich weiß auch nicht, was mich als Hauptbefürworter qualifiziert.

Die Liste der "Dislikes" erscheint mir ziemlich schwach. Ein besserer Weg, dies zu beweisen, könnte mit Code sein. Aggressiv und uninformiert zu sein ist eine schlechte Kombination, versuchen Sie, mindestens eine davon abzuschütteln.

@joyeecheung

Das einzige Mal, dass ich gezwungen war, im Browser auf XHR zurückzugreifen, war, als ich Fortschritte brauchte, obwohl ich denke, dass es mit den ReadableStreams des Browsers möglich ist, dasselbe mit einer etwas umständlichen API zu tun

Es ist derzeit:

const response = await fetch(url);
const total = Number(response.headers.get('content-length'));
let bytes = 0;
for await (const chunk of iterateStream(response.body)) {
  bytes += chunk.length;
  console.log(bytes, ' - ', total);
}

Ich mag es irgendwie, dass dies explizit ist, dass Sie dem Header Content-Length für die Gesamtsumme vertrauen. Obwohl ich gerne eine Art Beobachterobjekt einführen würde, um dies zu vereinfachen. Und Sie brauchen iterateStream nicht mehr, sobald ReadableStream Symbol.asyncIterator $ implementiert.

Außerdem scheint die Abrufspezifikation kein Timeout zu enthalten

Sie können dies mit Abbruchsignalen tun:

const controller = new AbortController();
const { signal } = controller;
setTimeout(() => controller.abort(), 3000);
const response = await fetch(url, { signal });

Dies gibt Ihnen die Flexibilität, auf komplexere Weise eine Zeitüberschreitung vorzunehmen, z. B. wenn für eine Art Zeitüberschreitung keine Bytes gesendet werden:

const controller = new AbortController();
const { signal } = controller;
let timeoutId;
const response = await fetch(url, { signal });
const resetTimer = () => {
  clearTimeout(timeoutId);
  timeoutId = setTimeout(() => controller.abort(), 3000);
};
resetTimer();

for await (const chunk of iterateStream(response.body)) {
  resetTimer();
  doSomething(chunk);
}

oder Agenten

Ja, so etwas haben wir noch nicht. Wir müssten über die Auswirkungen auf die Sicherheit im Internet nachdenken. Oder wir reservieren diese Option einfach für node in der Spezifikation, sodass wir niemals etwas mit dem gleichen Namen verwenden, um etwas anderes zu bedeuten.

(Ich eröffne dies erneut, da die Diskussion offensichtlich noch andauert und dieses Problem bisher nicht wirklich zu einem Abschluss gekommen ist.)

@jakearchibald oh je, hier sind wir wieder.

Fetch unterstützt den Content-Type-Header.

Jawohl. Das ist nicht dasselbe wie die tatsächliche Verwendung eines Inhaltstyps: Wenn ich JSON akzeptiere, dann gib mir JSON. Bitten Sie nicht jeden Benutzer, es manuell zu entschlüsseln.

JSON ist nicht Standard für was für was? Antwortstellen?

Inhaltstyp und akzeptiert.

Die Abruf-API unterstützt URL-Objekte, die searchParam unterstützen

Cool. Ist dies für Benutzer dokumentiert? Die einzige Fetch-Dokumentation, die ich je gesehen habe, sieht Leute, die Abfragezeichenfolgen manuell kodieren, und der Link, den Sie gerade gegeben haben, führt zu einem Implementierungsleitfaden für Browserentwickler.

So funktioniert HTTP. Der Methodenname ist eine Zeichenfolge.

Macht es nicht zum "Abrufen eines GET" oder wie auch immer Sie es weniger umständlich ausdrücken möchten. Eher wie jemand, der wirklich, wirklich den Namen 'fetch' anstelle von http verwenden wollte.

Ich weiß auch nicht, was mich als Hauptbefürworter qualifiziert.

(Bearbeiten: Erwähnung von Jakes Verhalten auf anderen Social-Media-Plattformen entfernt)

Ein besserer Weg, dies zu beweisen, könnte mit Code sein.

😂. Sie haben zu einer Spezifikation beigetragen, die 2018 nicht das tut, was Superagent 2012 getan hat, und Sie möchten Code, als hätte noch nie jemand einen HTTP-Client geschrieben, der vorher nicht saugt?

Dies ist nicht der Ort, allgemeine Meinungen über Fetch selbst zu diskutieren. Bitte konzentrieren Sie sich bei der Diskussion auf die Vorzüge der Implementierung von Fetch in Core.

Ich denke, dies ist eine DOM-API, die im Kern sehr schwer zu bekommen sein wird (aufgrund von Header-Safelists usw.), aber im Userland leicht genug zu bekommen ist.

@benjamingr Ich glaube nicht, dass der Knoten die Teile von Fetch erfüllen müsste, die für die Websicherheit da sind. Es wäre schön, Änderungen an der Spezifikation vorzunehmen, die es dem Knoten ermöglichen, dies zu tun, während er weiterhin konform ist, solange dies nicht zu kompliziert ist.

@jasnell Meine Hauptsorge ist, dass das Hinzufügen von Fetch zum Core immer noch erfordern würde, dass Benutzer entweder eine Reihe von Boilerplate-Codes für allgemeine Aufgaben schreiben oder eine High-Level-Bibliothek installieren müssten - infolgedessen würde das Hinzufügen von Fetch für Endbenutzer sehr wenig bewirken.

@jakearchibald du warst immer sehr bereit, den zusätzlichen Schritt für die Webplattform zu gehen – und wie du weißt – bin ich selbst ein Fetch-Fan :) Es gibt viele Dinge in Fetch, die sich sehr von Nodes PoV als Client unterscheiden.

Die API-Oberfläche von fetch ist eigentlich ziemlich groß und wird von Browsern (und Polyfills) nicht wirklich implementiert. Während das Abrufen selbst ziemlich stabil war, haben Browser dies nicht wirklich getan:

  • Fetch führt viele Klassen ein (Request, Response, Headers usw.), die neben der bestehenden Infrastruktur des Knotens für diese Dinge existieren würden.
  • Browser haben .body.getReader() noch nicht wirklich herausgefunden, es funktioniert in Chrome und _sorta_ in Firefox hinter einer Flagge. Welchen Typ würde es in Node zurückgeben? Ist es asyncIterable? Was macht .cancel am Körper?
  • AbortController würde bedeuten, zu diskutieren und festzulegen, wie die Stornierung in Node funktioniert, es mit unseren aktuellen Stornierungsmechanismen zu vergleichen usw.

Dinge, die auf ServiceWorker ausgerichtet sind, werden nicht funktionieren (obwohl ich nicht sicher bin, ob Sie Cloudflares neue_ish_ „serverseitige Service-Worker“-Sache gesehen haben, die wirklich cool ist!).

Fetch ist großartig, aber ich stimme nicht zu, dass es in Browsern so stabil oder bereit ist, wie die Leute hier erwähnen - die meisten Polyfills ignorieren offenkundig viele Randfälle.

Das Schlimmste – wir wissen beide, dass Fetch eine niedrigere API als XHR ist, die ziemlich leistungsfähiger ist, auf besseren Primitiven aufbaut und _Fähigkeiten_ hinzufügt. Keiner der Kommentare hier konzentrierte sich darauf - es hört sich so an, als ob Leute (allerdings keine Teilnehmer aus dem Kern) dies _aus Bequemlichkeit_ wollen, anstatt mit dem gezielten Ziel der Kompatibilität mit Web-Knoten-Plattformen oder der Offenlegung von Fähigkeiten.

Ich denke, es wäre interessant, einen _konkreten Vorschlag_ zu machen, der alle Änderungen bewertet, die in Node erforderlich wären, und ihn dann zu bewerten.

@thecodingdude

Ganz ehrlich, ich sehe nicht ein, warum diese Diskussion auf github stattfinden muss - zumindest sollte sie für Mitarbeiter gesperrt sein, die am Code arbeiten, und Diskussionen, die sich ausschließlich auf die Implementierung von Fetch konzentrieren, identisch mit dem Browser, wo möglich, und nicht mehr und nicht weniger.

Wir mögen Sperrprobleme hier wirklich nicht und tun dies nur, wenn wir sie nicht moderieren können. In dieser Ausgabe haben sich die Leute (während sie erhitzt waren) bemüht, höflich zu bleiben. Wir sehen, dass jeder, der hier antwortet oder liest, potenzielle Mitwirkende ist, und ich möchte jeden einladen, der dies liest und sich nicht sicher ist, wie er anfangen soll, mehr an Node to Reach Out teilzunehmen (meine E-Mail-Adresse ist benjamingr at gmail), und wir werden unser Bestes tun um für Sie interessante Möglichkeiten zu finden, einen Beitrag zu leisten.

Bisher lief diese Diskussion ziemlich gut, wobei Leute Argumente für beide Seiten vorbrachten. Danke, dass du das Thema eröffnet und hierher gebracht hast.


@mikemaccana Ich bitte Sie, diesen Kommentar selbst zu moderieren

oh je, hier sind wir wieder.

Abgesehen von diesem speziellen Kommentar habe ich Ihre Perspektive genossen und bitte darum, dass wir hier eine einladende Diskussionsumgebung bewahren – so weit wie möglich.

@benjamingr und @addaleax reichen bitte ein neues Problem in Bezug auf diese Diskussion ein. Ich hatte nie vor, eine Dose voller Würmer zu öffnen, was anscheinend passiert ist, und ich mag den allgemeinen Ton und die Haltung nicht, die @mikemaccana in dieser Ausgabe mit wiederholten Off-Topic-Bemerkungen und allgemeiner Nichthilfsbereitschaft gezeigt hat. Sein Beitragsstatus sollte überdacht werden.

Hitzige Diskussionen sind für Node nicht angebracht und die Anfrage war ganz einfach: In den Kern holen. Ich möchte Sie bitten, dieses Problem zu schließen/zu sperren und einen Vorschlag zu erstellen, wenn eine Aufnahme möglich ist. Wir brauchen keine 50 weiteren Kommentare, die hin und her streiten, da wir am Ende nirgendwo hingehen.

Ich denke, es wäre interessant, einen konkreten Vorschlag zu machen, der alle erforderlichen Änderungen in Node bewertet und dann bewertet.

Damit ist die Diskussion eigentlich beendet. Es wird viel einfacher sein, die Realisierbarkeit zu verstehen, wenn es einen Vorschlag gibt (wofür node-eps entwickelt wurde, aber leider nicht mehr passiert).

@thecodingdude Ebenso mag ich es nicht, dass Sie die Diskussion über die Vorzüge des Einbeziehens von Fetch nicht tolerieren und die Diskussion nur darauf beschränken möchten, wie es getan werden sollte, und nicht, ob es getan werden sollte - was eine berechtigte Sorge ist, ob Sie persönlich sind ob es Ihnen gefällt oder nicht.

@benjamingr

Fetch führt viele Klassen ein (Request, Response, Headers usw.), die neben der bestehenden Infrastruktur des Knotens für diese Dinge existieren würden.

Ja, ich kann mir nicht vorstellen, wie Sie fetch implementieren würden, ohne diese ebenfalls zu implementieren. Node hat WHATWG-URL implementiert, obwohl er seine eigenen Methoden hat, also denke ich, dass es hier dasselbe sein würde. Die Frage ist, ob es sich in diesem Fall lohnt.

Browser haben .body.getReader() noch nicht wirklich herausgefunden

Ich glaube nicht, dass das stimmt. Die Streams-Spezifikation ist ziemlich stabil, mit Implementierungen in Chrome, Edge und Safari. Firefox ist noch nicht da, aber ich habe gehört, dass sie ihre Implementierung abschließen.

Welchen Typ würde es in Node zurückgeben?

response.body müsste ein WHATWG-lesbarer Stream sein (was ich in https://github.com/nodejs/node/issues/19393#issuecomment-376443373 meinte).

Was macht .cancel am Körper?

Dies ist standardisiert. https://streams.spec.whatwg.org/#rs -cancel deckt die Stream-spezifischen Teile ab, und die Abrufspezifikation reagiert an mehreren Stellen auf den Abbruch.

AbortController würde bedeuten, zu diskutieren und festzulegen, wie der Abbruch in Node funktioniert

Ja, und AbortSignal ist ein EventTarget , was meiner Meinung nach ein EventEmitter im Knoten sein müsste. Das ist ein Kompatibilitätsproblem, das wir im Moment nicht wirklich vermeiden können.

Dinge, die auf ServiceWorker ausgerichtet sind, funktionieren nicht

Gibt es bestimmte Dinge, an die Sie denken? Die Verweise von Fetch auf Service Worker sind im Vergleich zu CORS (für das wir Problemumgehungen finden müssten) ziemlich unbedeutend.

Fetch ist großartig, aber ich stimme nicht zu, dass es in Browsern so stabil oder bereit ist

Ich denke nicht, dass es fair ist, das zu sagen. Es ist in Chrome, Firefox, Edge und Safari implementiert. Einige Implementierungen gibt es schon seit Jahren. Ok, Streams sind noch nicht Teil der Firefox-Implementierung, aber es ist der Ausreißer.

Ich denke, der "sollte Knoten implementieren?" Bei der Frage geht es eher um Kompatibilität und Eignung als um Stabilität. Ich habe hier kein starkes Gefühl, aber wenn Sie sagten: "Knoten implementiert entweder das Abrufen ohne Streams oder WHATWG-Streams, aber kein Abrufen. Wählen Sie." Ich würde auf jeden Fall WHATWG-Streams auswählen.

Ich denke, es wäre interessant, einen konkreten Vorschlag zu machen, der alle erforderlichen Änderungen in Node bewertet und dann bewertet.

+1 und die erforderlichen Änderungen in der Abrufspezifikation.

@mikemaccana fetch is fetch - wenn Sie den Standard aus irgendeinem Grund nicht mögen, dann nehmen Sie ihn mit WhatWG auf, dies ist nicht der richtige Ort, um Ihre Beschwerden darüber auszudrücken, was er tut / nicht tut. Ob dies tatsächlich im Kern landet, hängt ganz von den Node-Entwicklern ab, die für einige Jahre mit der Verantwortung beladen sein werden, es zu warten - hier kann "Userspace" praktischer sein, da es außerhalb des Bereichs von Nodes liegt, also wenn wir es wirklich sind Wenn _dies_ viel Diskussion erfordert, ist es vielleicht kein geeigneter Kandidat, um im Kern zu landen.

Vielleicht wären Sie so nett, WhatWG mit all den Problemen zu nerven, die Sie hier besprochen haben, und sie dazu zu bringen, die Spezifikation für Sie zu aktualisieren? Sie können hier ein Problem mit Ihren Bedenken einreichen.

@thecodingdude Ich bitte Sie, Ihre Formulierung hier zu berücksichtigen. Als Teil von Node fand ich die Diskussion (einschließlich Mikes die meiste Zeit) interessant. Bitte respektieren Sie unterschiedliche Sichtweisen und Erfahrungen und verwenden Sie eine einladende und integrative Sprache .

Wir führen _viel mehr_ Diskussionen als das, bevor wir ein Feature wie fetch einführen, es wird dann (als konkreter Vorschlag) dem TSC vorgelegt, der entscheidet, ob es sich lohnt, es in den Kern aufzunehmen, und dann machen wir _mehr_ Diskussionen über die Umsetzung vor der Landung.

@thecodingdude Hier geht es nicht um persönliche Beschwerden. Auch hier beziehe ich mich auf den Boilerplate-Code oder die Bibliotheken, die die meisten Knotenbenutzer installieren müssen, um fetch als HTTP-Client zu verwenden. Wie @Jamesernator bereits erwähnt hat, ist https://github.com/drufball/layered-apis/ der Ort, an dem bereits Diskussionen über High-Level-APIs stattfinden (danke James). Ich habe alles gesagt, was ich hier in früheren Kommentaren brauche. Ich habe das Gefühl, dass Sie dies ständig als persönliche Beschwerden falsch bezeichnen - wenn Sie damit aufhören würden, müsste ich nicht antworten.

Ich weiß, dass es gute Gründe geben kann, Standard-Dinge aufzunehmen, auch wenn sie suboptimal sind. Fair genug. Aber technische Grenzen, die die meisten Benutzer dazu zwingen, die gleichen Standardvorgaben anzuwenden, sind keine persönlichen Beschwerden.

Edit: Ich habe technische Mittel eingesetzt, um die Diskussion zwischen Ihnen und mir zu beenden.

Bearbeiten Sie 2, um eine einladendere Sprache pro @benjamingr- Anfrage zu verwenden.

@mikemaccana So wie es derzeit aussieht, verstößt dein Kommentar gegen unseren Verhaltenskodex. Bitte moderieren Sie es so schnell wie möglich , um unsere Standards zu erfüllen .

@benjamingr Entschuldigung, und fertig.

Fetch führt viele Klassen ein (Request, Response, Headers usw.), die neben der bestehenden Infrastruktur des Knotens für diese Dinge existieren würden.

Dies sind Klassen, die Fetch benötigen würde, aber es gibt auch APIs, die mit Fetch funktionieren, von denen ich denke, dass Entwickler erwarten würden, dass sie vorhanden sind, wenn Fetch im Kern implementiert ist. Ich denke an FormData und URLSearchParams , die beide praktische APIs sind, wenn Sie mit Formulardaten und URL-Parametern arbeiten. URLSearchParams sind bereits im Kern enthalten.

Wenn Fetch im Kern implementiert werden soll, würde man erwarten, dass auch FormData implementiert wird?

Ich würde es ein bisschen seltsam finden, Fecth und URLSearchParams im Kern zu haben, aber nicht FormData.

Ich habe die letzten paar Kommentare gelöscht. Aktionen einer Person in sozialen Medien fallen nicht in den Geltungsbereich unseres Issue-Trackers. Ich ermutige Sie dringend, Ihre Kommentare zu bearbeiten, um die Diskussion themenbezogen und konstruktiv zu halten.

Nur eine Frage: Wenn der Node-Kern ein globales fetch bekommt, bedeutet das, dass wir das implementieren könnten, indem wir node-fetch als eingebaute Abhängigkeit versenden, ähnlich wie wir es mit node-inspect tun

@addaleax technisch gesehen ja, aber ich denke, eine Sache, die wir tun möchten, ist, den zugrunde liegenden HTTP-Code getrennt zu halten, und ich möchte so viel davon wie möglich nativ implementieren

Ich stimme @devsnek zu. Außerdem scheint node-fetch den Webplattformtest nicht in seine Testsuite zu integrieren, die Tests dort sind gut genug für ein npm-Paket, aber wenn wir es in den Kern für Plattformisomorphismus und Anspruchskonformität stecken wollen, testen wir unsere Implementierung tatsächlich mit WPT wäre besser, selbst wenn wir die Tests portieren müssten, damit sie in einer Shell laufen können - und ich vermute, dass wir einige Interna hacken müssten, damit die Tests wie erwartet funktionieren.

@trygve-lie Wahrscheinlich auch AbortController [*] und Blob .

[*] Je nachdem, was mit dem Stornierungsvorschlag passiert, könnte es ein weiteres CancelSignal oder CancelToken oder was auch immer sein. Ich persönlich halte es für eine schlechte Idee, DOM-Ereignisse zu implementieren, nur um AbortController in Node zu erhalten, obwohl es dann zwei unterschiedliche Ereignistypen in Node geben würde.

In Bezug auf die Implementierungsdetails gibt es ein paar Dinge zu beachten, die sich aus meiner Erfahrung mit der Verwaltung von Node-Fetch und der Arbeit sowohl im Standardisierungsbereich als auch in Node.js ergeben.

Wir sollten keine Teile der Fetch-API implementieren.

Ich glaube, @jakearchibald hat diesen Punkt bereits angesprochen. Browser haben ein deutlich anderes Bedrohungsmodell als Node.js und erfordern viele Dinge, die in der Node.js-Umgebung keinen Sinn ergeben. Einige Beispiele sind:

Folglich ist nur eine kleine Teilmenge der Webplattformtests tatsächlich auf Node.js anwendbar. Es gibt eine beträchtliche Anzahl von Webplattformtests, die für Fetch verfügbar sind , aber viele von ihnen konzentrieren sich auf die Dinge, die ich oben erwähnt habe und die außerhalb des Bereichs einer möglichen Node.js-Implementierung liegen.

Web vs. Node.js

Response#body hängt vom WHATWG Streams Standard für Streaming-Daten (sowohl Eingabe als auch Ausgabe) ab. Ehrlich gesagt sind Webstreams fast immer besser gestaltet als die aktuelle Node.js-Streams-Infrastruktur; Derzeit gibt es jedoch wenig bis gar keine Userland-Unterstützung dafür.Sogar die Mittel, mit denen es in Chrome implementiert wird, gelten als veraltet . und während die Arbeit an der Spezifikation weitergeht, ist sie sicherlich nicht mehr am aktivsten . Dies stellt eine Node.js-Implementierung vor ein Dilemma: Implementieren Sie Webstreams und riskieren Sie Plattformkonsistenz und -akzeptanz, oder verwenden Sie Node.js-Streams für Response#body (was node-fetch tut) und verzichten Sie auf die Kompatibilität mit Browsern (wohl einer von die wichtigsten Gründe dafür, diese Funktion überhaupt in Node.js hinzuzufügen). Es gibt jedoch eine Reihe von nicht optimierten Konvertierungsdienstprogrammen zwischen Node.js-Streams und Webstreams.

Ganz zu schweigen von der Implementierung von Webstreams, die eine ziemlich schwergewichtige API-Oberfläche bereitstellt und zusätzliche Komplexität bei der Überbrückung zwischen JS und C++ mit sich bringt, einer stark optimierten Routine in bestehenden Node.js-Streams.

Andere Stellen, an denen das Dilemma zwischen Web und Node.js besteht, sind die Verwendung von DOMException in Abort Fetch , EventTarget in AbortSignal , FormData und der Support für die Datei-API über Blob (ein Thema, von dem ich mich erinnere, dass @jasnell daran interessiert ist).

JavaScript vs. C++

Dies geht zurück auf die Frage von @addaleax :

Wenn der Node-Kern ein globales fetch erhält, bedeutet das, dass wir das implementieren könnten, indem wir node-fetch als eingebaute Abhängigkeit versenden, ähnlich wie wir es mit node-inspect tun?

Die offensichtliche Antwort in diesem Fall wäre: „Wenn wir Webstreams verwenden, fangen Sie bei Null an und verwenden Sie C++; wenn wir weiterhin Node.js-Streams verwenden, verwenden Sie weiterhin JavaScript.“ Aber bevor man sich der ersten Option zuwendet, ist es wichtig, sich daran zu erinnern, dass unsere aktuelle http -Implementierung trotz ihrer vielen Macken sehr gut optimiert ist und es sicherlich viele, viele menschliche Stunden dauern wird, um eine so saubere Raumimplementierung auf Augenhöhe mit dem aktuellen http -Modul in Bezug auf die Leistung.

Ich bin dafür, im Wesentlichen eine In-Tree-Kopie von Node-Fetch zu haben, vielleicht mit einigen kernspezifischen Optimierungen. Aber ich würde ermutigen und mich freiwillig melden, um bei Experimenten mit einer Web Streams-Version zu helfen.

Bearbeiten :Löschen irreführende Aussagen über den Streams-Standard.

@TimothyGu Ich denke definitiv, dass response.body , ein Node-Stream zu sein, eine schlechte Idee wäre und im Allgemeinen den Punkt der Kompatibilität zunichte macht, wie Sie sagen.

Es könnte jedoch der Fall sein, dass es eine andere Node-spezifische Eigenschaft response.readableStream gibt, die verwendet werden könnte, wenn Node sich nicht sofort (oder überhaupt) zu einer vollständigen Stream-Implementierung verpflichten möchte. Die Leute könnten in der Zwischenzeit vorübergehend einen einfachen if-Zweig verwenden, und wenn beide Arten von ReadableStream Symbol.asyncIterator bekommen, hätten sie zumindest eine gemeinsame Konsummethode.

Die Leute könnten in der Zwischenzeit vorübergehend einen einfachen if-Zweig verwenden, und wenn beide Arten von ReadableStream Symbol.asyncIterator erhalten, hätten sie zumindest eine gemeinsame Verbrauchsmethode.

Dies ist bereits bei Node-Streams der Fall :)

@TimothyGu

Während die Arbeit an der [whatwg streams]-Spezifikation weitergeht, ist sie sicherlich nicht mehr am aktivsten.

Das ist ziemlich irreführend. Die Spezifikation ist ziemlich vollständig für den Satz von Funktionen, die sie hat, und die Arbeit konzentriert sich jetzt auf die Erstellung von Transformationsströmen, um das vorhandene Browserverhalten aufzudecken, z. B. https://github.com/whatwg/encoding/issues/72.

Der nächste Teil der Arbeit in der Streams-Spezifikation wird sich mit der Übertragbarkeit befassen, sodass Streams zwischen Workern verschoben werden können. Wir untersuchen auch aktiv Möglichkeiten, den Streaming-HTML-Parser verfügbar zu machen.

Zumindest für Chrome: Die Entwicklung von Streams ist für unsere Ziele zumindest in den nächsten Jahren wirklich wichtig.

Node-Leute, Webstandard-Leute und Browser-Leute leben nicht auf verschiedenen Planeten. Wir sind hier in Ordnung. Wenn Sie befürchten, dass ein Standard aufgegeben wird, können Sie mithilfe von Github-Statistiken einfach fragen, anstatt zu raten.

@jakearchibald Ich habe sicherlich nicht versucht zu implizieren, dass der Streams-Standard nicht gepflegt wird, sondern eher das Gefühl einzufangen, dass nur wenige Userland-Bibliotheken bereit sind, mit Webstreams umzugehen, was meiner Meinung nach eine angemessene Charakterisierung des Status quo ist. Entschuldigung für die irreführende Interpretation der GitHub-Statistiken.

@TimothyGu das ist fair. Ich denke, das liegt daran, dass wir nur Transformationsströme versenden, die meiner Meinung nach für das Userland unerlässlich sind.

Ich denke, es ist wichtig anzumerken, dass, wie Jake erwähnt, „Standard-Leute“ nicht auf einem anderen Planeten leben, was bedeutet, dass es vernünftig wäre, wenn ein so riesiges Ökosystem wie Node beschließen würde, eine originalgetreue und interoperable Implementierung des Fetch-Standards zu liefern Es wird erwartet, dass der Standard Änderungen und Anpassungen (mit angemessener Flexibilität und nach angemessener und gründlicher Diskussion) in Bereichen vornimmt, in denen solche Änderungen sinnvoll sind, solange sie das bereits bestehende Entwickler-Ökosystem nicht beschädigen oder anderweitig beeinträchtigen.

Wie aus der gründlichen Bewertung von @TimothyGu hervorgeht , sind die Node- und Browser-Welten bereits ziemlich weit auseinandergegangen, und dies wird auch in Zukunft so bleiben, es sei denn, es werden Schritte unternommen, um die beiden Welten zum Wohle der Allgemeinheit zusammenzuführen. Diese Konvergenz muss _irgendwo_ beginnen, und Fetch ist sowohl eine beliebte als auch eine leistungsstarke API, die in beiden Welten sehr sinnvoll ist (daher node-fetch und alle anderen Userland-Implementierungen davon). Ich glaube nicht, dass ein paar globale Klassen und Erschwinglichkeiten (die von der Implementierung benötigt werden) zu viele Leute stören werden, wenn sie sie nicht verwenden, aber sie werden mit Sicherheit zu leicht erhöhtem Wartungsaufwand und Dokumentationsaufwand führen, das muss sein sorgfältig ausgewertet.
Meine Vermutung hier ist jedoch, dass von der Plattformkonvergenz und der Erleichterung der Entwicklererfahrung profitiert wird (von niedrigeren Kosten für den Kontextwechsel für Full-Stack-Entwickler bis hin zur Vereinfachung von Electron, IoT, serverseitigem Rendering und anderen Codebasen, in denen FE+BE-Anwendungsfälle nebeneinander existieren). wird diese erhöhten Wartungskosten rechtfertigen.

Meiner Meinung nach wäre es sehr sinnvoll, eine experimentelle/MVP-Implementierung der API zu starten, auch wenn dies zunächst einige Einschränkungen und Auslassungen bedeutet (aber nur, wenn diese die zukünftige Implementierung und Unterstützung dieser ausgelassenen Funktionen nicht gefährden). Dies erfordert ein MVP, das sich auf zukünftige "Web-Kompatibilität" konzentriert, da eindeutig (und viele haben vor mir darauf hingewiesen) der resultierende Software-Isomorphismus und die plattformübergreifende Konsistenz einer der größten Gewinne der Konvergenz auf Fetch sind.
Langfristig sollte dies eine Konvergenz der zugrunde liegenden Strukturen (wie WhatWG Streams) bedeuten, aber diese Arbeit muss nicht unbedingt Teil der anfänglichen Erkundungen sein.

Ebenso wäre es nicht unmöglich (es wäre eher vorzuziehen), vorhandene WPT-Tests im Zusammenhang mit Fetch zu instrumentieren und/oder umzugestalten, um auch das Node-Ökosystem zu unterstützen. Auch diese sind nicht in Stein gemeißelt, wenn also die langfristige Konvergenz zwischen Node und dem Browser angestrebt wird, ist es möglich, diese Tests so zu verändern, dass sie den Anforderungen beider Seiten gerecht werden.

Eine weitere sehr interessante Anwendung von Fetch im Kern ist, dass derzeit beim Laden von WASM empfohlen wird, instantiateStreaming zu verwenden, das speziell für ein Response -Objekt gemäß der Fetch-Spezifikation definiert ist. Das schnelle universelle Laden von Web Assemblys könnte dabei ein interessanter Aspekt sein!

Ich denke, es ist ziemlich aufschlussreich, dass eines der ersten in Deno implementierten Features ein fetch Global ist - https://github.com/ry/deno/blob/7762b55432ba73f07f90414aa7d023bb0779f5de/globals.ts#L52. Dies ist nicht nur ein "nice to have", sondern ein kritischer Teil der Geschichte.

@guybedford Ich denke, das liegt nur daran, dass deno sich sehr auf die Browserähnlichkeit konzentriert ... siehe seine Unterstützung für HTTP-URLs in import -Pfaden. Um import Browser-Weise zu implementieren, müssten Sie den Fetch-Standard implementieren.

@guybedford das ist kaum zu holen - es ist nur eine sehr einfache API, die HTTP-Aufrufe macht, es fehlen viele der Fähigkeiten, die fetch fetch machen und meistens nur den Namen teilen.

können wir bitte nicht damit anfangen, node.js mit deno zu vergleichen

Ein experimentelles Projekt wie deno hat einen enormen Wert in Bezug darauf, was wir daraus lernen können, was unnötig zu versuchen und im Allgemeinen zu ignorieren scheint. Ich bin mit vielen Annahmen des Projekts nicht einverstanden (z. B. HTTPS-Importe), aber meiner Meinung nach kann es nur sinnvoll sein, Ideen und Erkenntnisse aus anderen Projekten als Inspiration in Node zu berücksichtigen.

Da dieses Thema nahe ist, bin ich wirklich verwirrt darüber, was wir in Zukunft tun werden.

Wird Node die fetch API implementieren oder nicht?

Wir bleiben in einem endlosen Gespräch über persönliche Vorlieben bezüglich der Spezifikation stecken, wo die meisten von us nur eine gemeinsame API zwischen dem Browser und Node wollen, auch bekannt als fetch -Spezifikation.

Sei vielleicht ein wenig pragmatisch und verbessere dich mit der Zeit.

Schauen Sie sich diese Zahlen an:

cross-fetch: 145,954 weekly downloads
isomorphic-fetch: 1,015,885 weekly downloads

Die Tatsache, dass wir 1 M (mit dem großen M) auf isomorphic-fetch haben, ist die Tatsache, dass wir alle das brauchen, und das Letzte, was wir wollen, ist eine Diskussion über die Spezifikation.

Wir brauchen das Feature einfach, da 1 Million wöchentliche Downloads die Tatsache zeigen, dass viele Quellcodes heute von den Paketen abhängen müssen, die im Grunde versuchen, dieses Problem zu beheben.

Sei einfach ein bisschen pragmatisch.

Bitte.

Die Tatsache, dass wir 1 M (mit dem großen M) beim isomorphen Holen haben, ist die Tatsache, dass wir alle dies brauchen; und das Letzte, was wir wollen, ist eine Diskussion über die Spezifikation.

1 Million Downloads ist weniger als ich bei mehreren Paketen habe, die ich bei der Wartung helfe (wie bluebird oder sinon) - aber ich habe nicht die Absicht oder möchte sie dem Kern hinzufügen. Es gibt mehrere andere HTTP-Bibliotheken:

  • Anfrage: 3.260.795 wöchentliche Downloads
  • Axios: 835.153 wöchentliche Downloads

Die Tatsache, dass etwas beliebt ist, bedeutet nicht, dass wir es zum Kern hinzufügen sollten (wie lodash, request oder express).

Die Hauptmotivation, so etwas wie fetch hinzuzufügen, ist Standardisierung und nicht Popularität :)

Die Hauptmotivation, so etwas wie Fetch hinzuzufügen, ist Standardisierung und nicht Popularität :)
@benjamingr

Aber ich hoffe, wir gehen nicht seitwärts, wie es dieser Thread bereits tut, anstatt uns darauf zu konzentrieren, wie wir vorankommen können.

Ja, Sie haben Recht, die Downloads gehören nicht zu Node, sondern rechtfertigen die Notwendigkeit, eine solche Standardisierung in Node zu haben. Ich wäre dumm, anders zu denken.

Mein Problem ist, dass ich mich auf isomorphic-[insert name here for cross-platform package wanted] -Pakete verlassen muss, weil 2009 ein Fehler gemacht wurde.

Und für andere, die bereits Deno-Gespräche verprügeln, lernen Sie von Deno die irreparablen Fehler in NodeJS, mit denen wir jetzt konfrontiert sind, und das Deno-Projekt versucht zu beheben (aus irgendeinem Grund, den ich nicht kenne, als brandneue Programmiersprache).

Wenn wir nicht bereit sind, bahnbrechende Änderungen einzuführen und darüber zu sprechen, werden wir gezwungen sein, die Geschichte zu wiederholen.

Vergessen Sie vor nicht allzu langer Zeit nicht IO vs. NodeJS, was einer der besten Schritte aller Zeiten für die Größten der Community war, sich zusammenzuschließen, selbst wenn es bedeutete, völlig unterschiedliche Richtungen in den Orgs zu haben, selbst wenn es bedeutete, eine zu haben viele bewegliche Teile.

Vielleicht ist dieses Problem und andere Probleme, die von demselben fundamental issue eingeführt werden könnten, ein Zeichen dafür, dass NodeJS selbst eine Auffrischung der Architektur und Implementierung benötigt.

Aber @benjamingr ja, du hast 100% recht.

weil 2009 ein Fehler gemacht wurde.

Wenn es um Fetch geht, hat sich der Fetch-Standard erst um 2014 herausgebildet, z. B. war dies der Commit , der fetch return zu einem Versprechen machte.

Vielleicht ist dieses Problem und andere Probleme, die durch dasselbe grundlegende Problem eingeführt werden könnten, ein Zeichen dafür, dass NodeJS selbst eine Auffrischung der Architektur und Implementierung benötigt.

Ich bezweifle, dass dies ohne Kompatibilitätsprobleme möglich ist - Refactoring kann sicher durchgeführt werden, aber die aktuelle Implementierung muss bestehen bleiben und schrittweise veraltet werden, wenn sie veraltet ist (andernfalls hätten wir new Buffer loswerden können jetzt, wo es TypedArrays schon so viele Jahre gibt). Einige Benutzer sind möglicherweise verärgert darüber, dass sie eine Reihe von selbst entwickelten APIs lernen müssen, die älter als die Web-API-Pendants sind, aber es werden noch mehr bestehende Benutzer verärgert sein, wenn ihr aktueller Code nicht mehr funktioniert.

Da dieses Thema nahe ist, bin ich wirklich verwirrt darüber, was wir in Zukunft tun werden.
Wird Node die Abruf-API implementieren oder nicht?

Soweit ich das beurteilen kann, wird sich keine Seite gegenseitig überzeugen, indem sie einfach argumentieren, dass eine bestimmte API populär genug ist, um im Kern zu sein, oder dass eine bestimmte API nicht für Server entwickelt wurde, also sollte sie nicht im Kern sein . Bisher scheint mir die Anmerkung von @TimothyGu in https://github.com/nodejs/node/issues/19393#issuecomment -376721984 der praktikabelste Vorschlag zu sein, aber nichts wird sich ändern, bis jemand eine PR öffnet oder veröffentlicht ein Proof-of-Concept und hat die Entschlossenheit, alle erforderlichen Änderungen vorzunehmen (einschließlich in der Spezifikation und in der Implementierung und im WPT), um das Endergebnis für Node angemessen zu machen, damit Leute, die es im Kern nicht wollen, dies tun können überzeugt sein. Die gleichen Argumente zu wiederholen, die in diesem Repo unzählige Male vorgebracht wurden, wird wahrscheinlich nicht zum Fortschritt beitragen, da sich die Arbeit nicht auf magische Weise erledigt, fürchte ich, und AFAICT, dies ist eine Menge Arbeit, die Sie nicht wirklich erzwingen können jemand freiwillig.

Im Januar hatte Axios 15.943.234, Isomorphic-Fetch 15.621.053 Downloads und Cross-Fetch 2.444.751 davon.

Um es ins rechte Licht zu rücken, das Paket react hat 20.767.762 Downloads.

Bitte erwägen Sie, dieses Problem erneut zu öffnen, Fetch ist eine der am häufigsten verwendeten Funktionen in node, und es ist nicht einmal im Kern enthalten.

Es kann ziemlich schwierig sein, die Parteien in diesem Thread zusammenzufassen. Einige wollen fetch() nicht, weil es zu niedrig ist, andere wollen es nicht, weil "High-Level-APIs im Userland besser gehandhabt werden".

Wie kann es sowohl auf niedrigem als auch auf hohem Niveau sein?

Alle Ihre bevorzugten beliebten HTTP-Clients wie Axios und Requests könnten ihre vorhandenen APIs problemlos auf diesem Kern aufbauen. Warum? Weil Standardisierung bedeutet, dass wir einen besseren Kern haben, und diejenigen, die keine API-Funktionen auf hohem Niveau wollen, können einfach diesen Kern verwenden.

HTTP/2-Unterstützung ist hier drüben, wenn Sie welche wollen. https://github.com/grantila/fetch-h2

Ich finde es toll, dass Browser-Land-JavaScript um einen einzigen HTTP-Client herum standardisiert wird, es macht das Erstellen von Middlewares viel einfacher.

PHP musste einen mühsamen Design-by-Committee-Ansatz durchlaufen, um die Standardisierung zu erreichen, und produzierte dabei mehrere PSRs: https://www.php-fig.org/psr/

Node hat derzeit eine Bajillion verschiedener HTTP-Clients, die nur mit einigen wenigen Middlewares funktionieren, und es gibt eine Handvoll funktionsschwacher VCR-Pakete, die darauf aufgeteilt sind, nur 1 oder 2 dieser Clients zu unterstützen. Wenn wir eine fetch()-Implementierung standardisieren könnten, könnte mehr Arbeit in Tools fließen, die mit diesem Standardkern arbeiten, anstatt die Arbeit auf so viele verschiedene kundenspezifische Lösungen zu verteilen.

Standards sind gut, und die Implementierung einer Standardimplementierung für allgemeine Aktivitäten wie das Erstellen einer HTTP-Anforderung in Node würde allen eine Menge Ärger ersparen.

Ich denke, das Wichtigste, was hier fehlt, ist jemand, der wirklich daran arbeitet. Dies ist ein Unterfangen, das wahrscheinlich in Hunderttausenden von Zeilen gemessen wird, und Knoten hat keine Mitarbeiter wie Browser, um dies zu implementieren.

Kann Node nicht einfach die Implementierung aus einem Browser wie Chromium kopieren und einfügen?

@sheerun nein, können wir nicht, die interne Infrastruktur ist zu unterschiedlich, und es gibt auch unterschiedliche Ziele bei den Implementierungen. Browser haben viele Umleitungen, um sicherzustellen, dass Dinge wie CORS nicht verletzt werden, aber impl von node hätte nicht einmal CORS und wir würden uns wahrscheinlich auf die Leistung konzentrieren wollen.

Dann wäre vielleicht ein besserer Ansatz, Polyfill wie https://www.npmjs.com/package/node-fetch als offizielle API zu kopieren und einzufügen und es dann schrittweise mit nativem Code neu zu schreiben. Alles, was alle interessiert, ist die standardisierte Methode zum Ausführen des HTTP-Abrufs im Knoten, nicht dass es nativ in C++ implementiert ist.

Leistung ist nur eine Überlegung. Es ist ein wichtiger, aber nicht der einzige. Das andere Problem ist, ob Node.js mit der richtigen Spezifikationskonformität implementiert werden kann. Zumindest müsste auch die Streams-API implementiert werden und einige globale Zustandsprobleme müssten untersucht werden. Ich habe eine Implementierung, die ich durchgeführt habe und die ich nicht weiter verfolgen möchte, da das impl aufgrund von Anpassungen, die erforderlich sind, um es in Node.js einzufügen, nicht vollständig der Spezifikation entspricht

Eine Teilmenge der fetch API würde wahrscheinlich auch funktionieren. Ich verstehe, dass eine 100-prozentige Konformität problematisch sein kann, aber ich denke nicht, dass dies für die meisten Anwendungen erforderlich ist (oder sogar möglich ist, dass Sie einige Funktionen wie CORS einfach nicht implementieren können, da sie für diese Umgebung nicht gelten).

Ich denke, der beste Ansatz wäre, zu entscheiden, was die "Common API" von fetch ist, und dann Implementierungen für Browser (z. B. CORS ist enthalten) und Node (z. B. Puffer wird anstelle von Streams implementiert) zu unterscheiden. Jeder sollte in Ordnung sein, solange Node die fetch -API nicht ändert , sondern stattdessen einige Teile davon überspringt und auch einige zusätzliche Nur-Knoten-API hinzufügt.

Bitte beachten Sie, dass die API von Node-Fetch ebenfalls nicht 100 % browserkompatibel ist, aber gut genug für isomorphe Apps ist und Entwickler keine Probleme damit haben.

Bei den Request- und Response- Typen ist das einzige Feld, das Streams verwendet, body , und die meisten APIs benötigen überhaupt keine Streams. Ich denke, es ist in Ordnung, wenn Sie die Unterstützung dieses Felds zumindest für 1.0 überspringen.

Für einen weiteren Datenpunkt erwägt das Next.js-Projekt dringend, fetch automatisch zur Serverlaufzeit hinzuzufügen.

Serverless verwischt die Grenzen zwischen der Ausführung von Code auf dem Server und dem Client. Jeder einzelne unserer Kunden installiert Next.js und bringt dann isomorphic-fetch , node-fetch , fetch-h2 usw.

Es ist letztendlich eine Verschwendung von Zeit und Ressourcen und eine große Quelle von Sicherheitsproblemen, unvollständigen und unterschiedlichen Implementierungen, der Vertiefung von schwarzen Löchern in node_modules usw.

Ich war anfangs dagegen, fetch in Node.js zu verwenden, aber genau das ist es, wo wir unweigerlich hinsteuern. Ich würde Chrome sogar gerne als meine Serverlaufzeit ausführen, da ich mehr Funktionsparität zwischen den Plattformen und eine konsistente Entwicklererfahrung möchte :)

Ich war anfangs dagegen, dass fetch in Node.js enthalten ist, aber genau das ist es, worauf wir unweigerlich zusteuern. Ich würde Chrome sogar gerne als meine Serverlaufzeit ausführen, da ich mehr Funktionsparität zwischen den Plattformen und eine konsistente Entwicklererfahrung möchte :)

Dem stimme ich mit der Zeit immer mehr zu. Ich denke, wir müssen herausfinden, wie wir EventTarget und EventEmitter und unsere Streams mit Webstreams in Einklang bringen können, was meiner Meinung nach derzeit der größte Blocker ist, um eine Fetch-ähnliche Abstraktion in Node zu landen.

Meine Hauptsorge ist, dass Node.js kein Browser ist. Es hatte nie die gleichen Garantien und das gleiche Maß an Benutzerisolierung und Sicherheit, das Teil eines Webbrowsers ist. Diese Kompromisse waren erforderlich, um eine leistungsfähige und zuverlässige serverseitige Plattform bereitzustellen.

In einem Browser gibt es nur einen einzigen Benutzer. In Node.js haben wir potenziell Zehntausende. Die Abruf-API ist für einen einzelnen Benutzer konzipiert: Sie verwendet den Browser-Verbindungspool, TLS-Konfigurationen, Keep-Alive-Einstellungen, Caching usw. Ich bin fest davon überzeugt, dass wir nicht die vollständige Abrufspezifikation implementieren können, und was wir beenden up with würde erheblich vom Standard abweichen, um es nicht in eine globale zu stellen.

Es ist erwähnenswert, dass AWS Lambda dies 1:1 zwischen einem Prozess und einem Benutzer garantiert. Es hat einen hohen Preis: TLS-Verbindungen werden nicht offen gehalten, und die Latenz ist unter anderem höher. (Andere serverlose Umgebungen haben nicht dieselbe Einschränkung).

Ich stimme zu, dass wir etwas dagegen unternehmen und den Prozess beginnen sollten, einen Konsens über Fetch zu erzielen.

@joyeecheung kann das Standards-Team daran arbeiten?

Die WHATWG-URL-Implementierung von @mcollina Node ist auch nicht global, daher denke ich nicht, dass es sich lohnt, sich darüber allzu viele Gedanken zu machen.

Ich denke, der beste Ansatz wäre, eine http.createFetch(opts)-API zu haben, die das Agentenmodell http/https/http2/http3 so umschließt, dass es a) mit der Node.js-API kohärent ist und b) mit den gängigsten kompatibel ist Anwendungsfälle für die Browserspezifikation c) leicht abzufangen (unsere aktuelle API ist extrem schwer zu packen, siehe http://npm.im/nock).

Ich denke, das könnte uns genug Flexibilität geben, um die meisten Anwendungsfälle zu lösen. Es wird definitiv einige wesentliche Unterschiede auf der Semantik-/Verhaltensebene (Caching, Verbindungspooling und Sicherheit) geben, weshalb ich mich frage, ob wir dies zunächst „Fetch“ nennen sollten – Fetch ist jedoch äußerst beliebt und die Community ist mit node -fetch und andere Polyfills, also mache ich mir nicht so viele Gedanken darüber, etwas deutlich anderes zu haben. Wir brauchen definitiv eine neue HTTP-Client-API im Kern, da unser aktuelles Modell stark altert.

(Beachten Sie, dass es auch signifikante Unterschiede in der WHATWG-URL-Implementierung gibt, und wir machen keine gute Arbeit, diese zu sagen).

Der WHATWG-Abruf ignoriert derzeit das Caching, was mich zwar traurig macht, aber ich hätte lieber eine Standard-API ohne Caching als keine Standard-API.

--
Phil Stör
@philsturgeon

Am 26. April 2019 um 08:18 schrieb Matteo Collina [email protected] :

Ich denke, der beste Ansatz wäre, eine http.createFetch(opts)-API zu haben, die das Agentenmodell http/https/http2/http3 so umschließt, dass es a) mit der Node.js-API kohärent ist und b) mit den gängigsten kompatibel ist Anwendungsfälle für die Browserspezifikation c) leicht abzufangen (unsere aktuelle API ist extrem schwer zu packen, siehe http://npm.im/nock).

Ich denke, das könnte uns genug Flexibilität geben, um die meisten Anwendungsfälle zu lösen. Es wird definitiv einige wesentliche Unterschiede auf der Semantik-/Verhaltensebene (Caching, Verbindungspooling und Sicherheit) geben, weshalb ich mich frage, ob wir dies zunächst „Fetch“ nennen sollten – Fetch ist jedoch äußerst beliebt und die Community ist mit node -fetch und andere Polyfills, also mache ich mir nicht so viele Gedanken darüber, etwas deutlich anderes zu haben. Wir brauchen definitiv eine neue HTTP-Client-API im Kern, da unser aktuelles Modell stark altert.

(Beachten Sie, dass es auch signifikante Unterschiede in der WHATWG-URL-Implementierung gibt, und wir machen keine gute Arbeit, diese zu sagen).


Sie erhalten dies, weil Sie kommentiert haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.

@philsturgeon

Der WHATWG-Abruf ignoriert derzeit das Caching

Das ist… falsch. Große Teile der Spezifikation und der API sind dem Aushandeln von Caches gewidmet.

Wie kommst du darauf, dass fetch Caches ignoriert?

Tut mir leid, ich rede aus meinem Hintern. Ich meinte, dass die GitHub-Implementierung von fetch() (die auf non als „node-fetch“) das Caching ignoriert.

--
Phil Stör
@philsturgeon

Am 26. April 2019 um 09:33 Uhr schrieb Jake Archibald [email protected] :

@philsturgeon

Der WHATWG-Abruf ignoriert derzeit das Caching

Das ist… falsch. Große Teile der Spezifikation und der API sind dem Aushandeln von Caches gewidmet.

Wie kommst du darauf, dass fetch Caches ignoriert?


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.

+1 zu einem neuen Impl, vielleicht können wir sogar Napi verwenden, um es in den Kern zu integrieren

Ich bin absolut dafür, ein npm-Modul anzubieten, das wir dann als fetch verfügbar machen, unabhängig davon, ob es sich um eine neue Implementierung handelt oder nicht.

@mcollina Ich glaube nicht, dass sich jemand mit der vollständigen Abrufspezifikation in Bezug auf das Caching befasst. Node.js ist kein Browser, aber immer mehr Code wird zwischen Client und Server geteilt, und obwohl wir nicht die gleichen Garantien haben, wenn unsere API-Oberfläche modernisiert wird (wie fs.promises), denke ich, dass Fetch nicht schlecht passt. Es macht Streams ziemlich sauber, Backpressure, Cache-Handling und andere Dinge.

Es gibt Teile davon, die sich mit der Cross-Origin-Richtlinie befassen, die wir nicht brauchen/wollen, aber ansonsten denke ich, dass ein einziges modernes Primitiv auf niedriger Ebene für die Durchführung von HTTP-Anforderungen im Kern von Vorteil ist (Fetch ist eine niedrige Ebene primitiv für Anfragen).

Was ist mit etwas wie (und ich bin bikeshedding):

  • Erstellen Sie im Kern eine EventTarget Unterklasse von EventEmitter .
  • Erstellen Sie eine WhatWG-Stream-Unterklasse (oder eine ähnliche) von ReadableStream.
  • Blobs werden ausdrücklich nicht unterstützt (aber vielleicht später hinzugefügt?).
  • Fügen Sie fetch als experimentell über http hinzu.

Ich bin ziemlich fest darin, keinen einzigen globalen Verbindungspool, Sicherheitseinstellungen, Caching usw. zu haben. Ich bin mit Ihrem Plan einverstanden, solange wir all das erstellen und abreißen können, wenn wir wollen. Node.js wird außerordentlich besser, da es den standardmäßigen globalen Agenten losgeworden ist, und ich möchte wirklich nicht, dass diese Situation noch einmal passiert.

(abzüglich einiger Details zur Streams-Interop, aber das sind API-Details).

Einerseits würde ich gerne sehen, dass sich Fetch im Kern von nodejs befindet.
Andererseits denke ich, dass die Leute ihre Erwartungen dämpfen sollten, da ich vermute, dass das Endergebnis viele Benutzer enttäuschen wird.

Gründe dafür:

  • Leute, die nach nativer Fetch-Unterstützung suchen, möchten sie in einer isomorphen Umgebung verwenden: dh. Sie wollen den gleichen Code schreiben und auf Browsern, Nodejs und sogar React-Native laufen.
  • Auch wenn wir Themen wie cookie , cache , protocol-relative url und error handling überspringen, bleibt das Problem mit WHATWG Stream bestehen.
  • Meine starke Präferenz ist, dass nodejs Fetch mit WHATWG Stream implementiert, aber das bedeutet, dass die API nicht mit den meisten vorhandenen Bibliotheken spielt (sicher, Sie können sie in nodejs-Stream konvertieren, aber der Interop-Schritt selbst ist nicht isomorph).
  • Auf der anderen Seite sehe ich bei der mehrfachen Implementierung von Fetch mit nodejs-Stream keinen Grund für einen weiteren Fetch, der von Natur aus nicht isomorph ist. (Wir können uns nicht einmal auf einfache Dinge wie highWaterMark einigen, die dazu führen, dass Code in Browsern gut läuft, aber auf nodejs mit Gegendruck konfrontiert wird.)
  • Ich fordere die Leute auf, die Einschränkungen bestehender Fetch-Implementierungen zu lesen und zu erfahren, was wir tun mussten, um Fetch serverseitig schmackhafter zu machen, und dann zu überlegen, ob dies der Fetch ist, den Sie sich wünschen.

https://github.com/bitinn/node-fetch/blob/master/LIMITS.md

@bitinn was ist mit einer Node-Stream-Unterklasse, die die Whatwg-Stream-Schnittstelle implementiert?

Wie wichtig sind Ihrer Meinung nach Cookie-/Cache-/Protokoll-relative URLs hier? Ich denke, Fehlerbehandlung und Streams sind lösbar und Node-Streams sind sowieso schon asynchronisierbar :)

@benjamingr Das könnte ein guter Kompromiss sein.

Vorteile:

  • Leute, die nur einen einheitlichen Fetch wollen, der den H1/H2-Unterschied abstrahiert, werden glücklich sein, sie verwenden Fetch nicht unbedingt in einem isomorphen Sinne, sondern mögen die Tatsache, dass API ähnlich funktioniert, also weniger Dinge zu lernen und zu beherrschen.
  • Wenn die Fetch-API im Knoten vorhanden ist, selbst eine begrenzte, wird die umgebende Infrastruktur verschoben, sodass HTTP-bezogener Code im Laufe der Zeit isomorpher wird.

Nachteile:

  • Leute, die die Fetch-API in einem isomorphen Sinne verwenden, werden mehr als nur fetch() verlangen: Zu Beginn gibt es new Response() , new Request() , new Headers() , Blob , FormData , AbortSignal , dann führt das inhärente Fehlen von cache und cookie dazu, dass Leute nicht isomorphen Code schreiben.
  • Leute, die mehr Kontrolle als Standard-Fetch wollen, werden mehr als nur fetch() verlangen: Zu Beginn müssen sie benutzerdefinierte agent verwenden, dann gibt es Dinge wie die Kontrolle der Download-Größe, den Umgang mit unendlichen Antworten, Steckdosenunterstützung usw.

Die Fetch-API ist so konzipiert, dass sie einige Dinge sehr gut macht, andere jedoch nicht. Es wird schwierig sein, die Spezifikation in diese Richtung zu bewegen, daher müssen Sie fast immer Urteile fällen, die die Leute entfremden.

Sehen Sie sich unsere Tests an (das sind 2700 Zeilen, wenn der tatsächliche Code nur 500 Zeilen umfasst):

https://github.com/bitinn/node-fetch/blob/master/test/test.js

Sehen Sie auch, wie die Fehlerbehandlung angesichts der vorhandenen Fetch-Spezifikation nicht trivial ist:

https://github.com/bitinn/node-fetch/issues/549

@bitinn nimmst du zufällig am Summit (https://github.com/nodejs/summit/issues) teil? Ich denke, es wäre großartig, dies mit anderen interessierten Parteien (wie @mcollina und vielleicht @jakearchibald , wenn er teilnimmt) zu besprechen und die Herausforderungen aufzuzählen, die beim Hinzufügen von Fetch zum Core bestehen.

cc @nodejs/open-standards

Ich möchte auch hinzufügen, dass ich es in der Vergangenheit als angenehme Erfahrung empfunden habe, an der Fetch-Spezifikation mitzuarbeiten, und dass die Leute, die an Fetch arbeiten, sehr einladend und freundlich sind - also denke ich definitiv, dass wir diese Leute einbeziehen sollten, wenn wir dies tun.

Ich denke, es wäre wichtig, dass Node sicherstellt, dass es sich nicht anders verhält, wenn nicht standardmäßige Optionen mit fetch verwendet werden.

Nehmen Sie zum Beispiel Anmeldeinformationen (Cookies) und nehmen Sie an, dass Node nicht mit Unterstützung für Anmeldeinformationen ausgeliefert wurde. Dann wäre es meiner Meinung nach besser, wenn Node einen Fehler auf fetch(someUrl, { credentials: 'include' }) ausgeben würde, anstatt die Anmeldeinformationen stillschweigend zu ignorieren. Knoten würde stattdessen seine eigene neue Option einführen, z. B. 'bypass' und fetch(someUrl, { credentials: 'bypass' }) (Name des Fahrradschuppens) verwenden.

Jetzt wäre es offensichtlich ein großer Schmerz, fetch(someUrl, { credentials: isNode ? 'bypass' : 'omit' }) tun zu müssen, stattdessen könnte man einfach sagen, dass alle Optionen, die nicht bereitgestellt werden, nur die Standardeinstellung des Hosts verwenden, die im Fall von Node 'bypass' wäre. Noch besser wäre es, wenn die Abrufspezifikation selbst widerspiegeln könnte, dass Nicht-Browser-Abrufimplementierungen möglicherweise unterschiedliche Standardwerte für verschiedene Optionen verwenden.

Ebenso denke ich, dass es sehr wichtig ist, dass Node, wenn er auf nicht kompatible Weise von der Spezifikation abweichen soll (z. B. um zusätzliche Daten oder dergleichen offenzulegen), dies unter Verwendung neuer Eigenschaften tun sollte, anstatt sich anders als die vorhandenen Eigenschaften zu verhalten.


Meiner persönlichen Meinung nach könnte es sich sogar lohnen, Funktionen wie Cookies/CORS/Caches/etc innerhalb von Node in Betracht zu ziehen (ob ein globaler Abruf mit diesen Funktionen bereitgestellt wird oder nicht, ist mir persönlich egal).

Zum Beispiel könnte Node eine Fabrik mit Dingen wie Keksdosen und ähnlichem in Betracht ziehen, die anderen http-Bibliotheken ähneln:

import { makeFetch, createPersistentCookieJar, createInMemoryCache } from 'fetch'

const cache = createInMemoryCache({ limit: os.totalmem() / 4 })
const cookieJar = createPersistentCookieJar('./cookies.cookiejar')

const fetch = makeFetch({ cache, cookieJar, origin: 'https://mycoolwebsite.com' })

// Use fetch like a browser fetch

Trotzdem denke ich, dass es für Node viel besser wäre, eine gute Teilmenge von Fetch zu haben, als nicht alles zu implementieren oder ewig an einer vollständigen Implementierung zu arbeiten.

Nehmen Sie zum Beispiel Anmeldeinformationen (Cookies) und nehmen Sie an, dass Node keine Unterstützung für Anmeldeinformationen enthält. Dann wäre es meiner Meinung nach besser, wenn Node einen Fehler auf fetch(someUrl, { credentials: 'include' }) ausgibt, anstatt die Option für Anmeldeinformationen stillschweigend zu ignorieren.

Ich bin mir nicht sicher. Wenn Sie im Browser fetch(someUrl, { credentials: 'include' }) anrufen, wenn keine Anmeldeinformationen vorhanden sind (neuer Website-Besuch, Inkognito-Modus, gerade gelöschte Cookies), wird er nicht abgelehnt.

Es fühlt sich an, als ob Node sich wie ein Browser ohne Anmeldeinformationen verhalten sollte.

Knoten würde stattdessen seine eigene neue Option einführen, z. B. 'bypass' und fetch(someUrl, { credentials: 'bypass' }) (Name des Fahrradschuppens) verwenden.

Wie würde sich das von „weglassen“ unterscheiden? Ich denke nicht, dass Node neue Optionen hinzufügen sollte, ohne sie der Spezifikation hinzuzufügen.

@jakearchibald Ich glaube, ich wurde mit CORS verwechselt, als ich versuchte, ein Beispiel zu geben. Mein Beispiel hätte fetch(someUrl, { mode: 'bypass-cors' }) lauten sollen, wo wir CORS vollständig ignorieren, aber trotzdem die Antwort lesen können, da dies das typische Verhalten ist, das die meisten Leute wollen Knoten.

Offensichtlich gibt es Alternativen:

  • Lassen Sie einfach das Lesen von normalerweise undurchsichtigen Antworten in Node zu (behandeln Sie file:/// als Ursprung).
  • Fügen Sie einen weiteren Mechanismus nur für Node zum Lesen undurchsichtiger Antworten hinzu (behandeln Sie file:/// als Ursprung)
  • Ignorieren Sie einfach alle cors-bezogenen Flags und lesen Sie alle Antworten

Ich würde es vorziehen, auf Nummer sicher zu gehen und mit einer der ersten drei Ideen zu gehen und vorhandene Flags nicht einfach zu ignorieren (stattdessen Dinge zu verwenden, die der Knoten nicht unterstützen möchte, wie no-cors oder tatsächlich unterstützen Ihnen)

An @Jamesernator und andere, die diesen Thread lesen.

Das Schwierige daran, Fetch so nah wie möglich an die Spezifikation zu bringen, ist das Fehlen von context , in Browsern ist das selbstverständlich: cookies , cache , sessions können alle als Teil davon betrachtet werden.

Dies ist wahrscheinlich der Grund, warum fetch-h2 sein Kontextobjekt erfunden hat, weil es für HTTP/2 natürlicher ist.

Dies ist auch der Grund, warum node-fetch es nicht getan hat, weil uns die Tatsache gefällt, dass nodejs HTTP/1 kontextlos ist und Sie Verbindungen über benutzerdefinierte agent steuern.

Meine Meinung: Die Dinge werden einfacher, wenn nodejs eine neue HTTP-Abstraktionsschicht bereitstellen kann, bei der Sie nicht an HTTP/1 oder HTTP/2 denken. Ja, es ist so schwer wie das Schreiben eines spezifikationskonformen Abrufs, aber Sie müssen nicht spezifikationskonform sein, wenn Sie eine neue API erfinden, _Sie können den Konformitätsschritt effektiv verzögern, wenn Sie diese API in Fetch einschließen._


Das zweite Problem ist einfach API, Sie dürfen Dinge wie new Response(new FormData()).Blob() tun und per Spezifikation sollte es einfach funktionieren.

Meine Meinung: Die Dinge werden einfacher, wenn nodejs Dinge wie Blob , FormData und WHATWG Stream überhaupt erst bereitstellen kann. Ohne sie verlassen Sie sich auf das Userland, um eine konforme Lösung zu implementieren, aber weder Blob noch FormData bieten eine Möglichkeit, sich selbst zuverlässig zu „erkennen“, also verlassen Sie sich auf das Raten von Namen und das Eintippen von APIs. (Das macht node-fetch .)


Das dritte Problem ist die Spezifikationsänderung. Es gab Fälle, in denen Fetch-Spezifikationsänderungen die vorhandene API unterbrachen. Zum Beispiel ist das Lesen Set-Cookie -Headern immer noch ein Hack in node-fetch , da die Headers -API erwartet, dass get(name) eine einzelne Zeichenfolge ist, obwohl Sie mehrere Set-Cookie haben können.

Browser müssen sich wegen ihrer context (früher gab es getAll() aber diese API wurde fallengelassen) keine Gedanken darüber machen, die Spezifikation musste nie verschoben und eine zusätzliche API hinzugefügt werden.

Meine Meinung: Wenn nodejs offiziell die Absicht zeigt, Fetch zu implementieren, dann habe ich das Gefühl, dass das Fetch-Spezifikationsteam davon überzeugt werden könnte, eine spezielle API für Dinge wie Set-Cookie hinzuzufügen (mit Ausnahme des Sicherheitsproblems). Dies erstreckt sich möglicherweise auf andere spezifikationsbezogene Dilemmas.

Thx fürs Lesen.


@benjamingr Leider gehe ich nicht zum Gipfel (arbeite heutzutage hauptsächlich in C#), aber ich hoffe sehr, dass das nodejs-Team dieses Problem mit dem Fetch-Spec-Team und den Browseranbietern besprechen kann.

Vielleicht wäre es besser, den Spieß umzudrehen und anstatt zu versuchen, die offizielle fetch -Spezifikation zu 100 % zu erfüllen, eine eigene fetch -Spezifikation des Knotens zu erstellen, die einen einfacheren Umfang als die ursprüngliche fetch $-Spezifikation hat ist auch kinderleicht zu polyfill mit original fetch (idealerweise 1:1 API). Mit dieser Änderung müssen Sie die globalen fetch oder Request oder Response nicht mehr verfügbar machen, da Sie nicht mehr versuchen, das ursprüngliche fetch zu implementieren.

Eine API könnte etwa so aussehen:

const { fetch, Response, Request } = require('http')

Und auf der Browserseite würde es in etwas umgewandelt werden wie:

const { fetch, Response, Request } = window

Ich habe privat mit @jakearchibald gesprochen (und nach dem Gipfel gefragt) und da viele der beteiligten Parteien nicht teilnehmen werden, habe ich darüber nachgedacht, dies vielleicht in ein kleines Team von Interessenten zu integrieren.

@jakearchibald @bitinn und alle anderen interessierten Parteien: Ich denke, das lohnt sich und ich denke, wir sollten darüber diskutieren. Ich denke, Anfang Juni (nach der JSConf und dem Gipfel) wäre ein guter Zeitrahmen, um darüber zu diskutieren.

@nodejs/open-standards wdyt?

@sheerun zu deinem Kommentar,

Ich würde es vorziehen, dass wir diese Dinge in das global -Objekt einfügen, damit wir keine Sonderfälle erstellen müssen, es sei denn, es gibt einen technischen Grund dafür (ich habe nichts dagegen, Dinge erneut zu exportieren).

const { fetch, Response, Request } = globalThis; // don't forget that we have this now

Wenn es Implementierungsunterschiede geben wird, ist ein Modulansatz sinnvoller, wie @sheerun beschreibt, da ein Browser-Shim für den Node-Fall entworfen werden kann, genau wie bei Arbeitern.

@yordis Es ist nur ein Beispiel. Ich bin mir ziemlich sicher, dass das Shim nicht so einfach wäre und eher so etwas wie:

const { fetch, Response, Request } = __makeNodeFetch();

wo __makeNodeFetch durch Polyfilling Bundler/Library injiziert wird

BEARBEITEN: Ich würde auch vorschlagen, dass das offizielle Shim vom Knotenteam versendet wird, anstatt von einem Drittanbieter erstellt zu werden

Hey, nur ein Update, dass wir uns auf dem Gipfel darüber getroffen haben, und hier sind die Notizen https://docs.google.com/document/d/1tn_-0S_FG_sla81wFohi8Sc8YI5PJiTopEzSA7UaLKM/edit , es gibt auch die oben verlinkte PR, die drin ist ein sehr frühes Stadium.

Wir brauchen aktiv Menschen, die sich engagieren und bei den oben genannten Problemen helfen.

@benjamingr Frage aus Unwissenheit.

Wie schwierig wäre es, die Deno-Implementierung von fetch in NodeJS anzupassen? (konzentrieren Sie sich bitte nicht auf Deno vs. NodeJS 🙏)

Wenn ich mir den Code anschaue, scheint es, dass er tragbar sein könnte, aber ich bin mir nicht sicher, welchen Wänden ich dabei gegenüberstehen werde.

Hat das jemand versucht?

Sollen wir das versuchen?

Wie schwer wäre es, die Deno-Implementierung von Fetch in NodeJS anzupassen?

Sehr, die Implementierung von Deno ist sehr unvollständig und es fehlen viele Funktionen. Beginnend mit dem Knotenabruf wie dieser PR sind bereits viel mehr Funktionen vollständig. Darüber hinaus funktioniert die Implementierung von Deno, indem sie sich mit Flatbuffern in Tokio einklinkt (wir verwenden keines davon) und würde für node wirklich nicht viel Sinn machen.

(Es gibt keine Feindschaft zwischen Deno und Node.js, es ist wirklich kein Wettbewerb :) )

Ich kann mir nicht vorstellen, wie jemand alle Kommentare in diesem Thread lesen und eine Entscheidung treffen wird. Natürlich ist es gut, darüber eine öffentliche Debatte zu führen, aber es ist auch praktisch unmöglich, einen Konsens zu erzielen. Ich kann mir vorstellen, dass das Kernteam einige (oder die meisten) Rückmeldungen lesen und ihre Entscheidungen treffen wird.

@bitinn Kommentar:

Das dritte Problem ist die Spezifikationsänderung. Es gab Fälle, in denen Fetch-Spezifikationsänderungen die vorhandene API unterbrachen. Beispielsweise ist das Lesen von Set-Cookie-Headern immer noch ein Hack beim Knotenabruf, da die Header-API erwartet, dass get(name) eine einzelne Zeichenfolge ist, obwohl Sie mehrere Set-Cookie-Header haben können.

Ich habe gerade https://github.com/whatwg/fetch/issues/973 geöffnet, um die Diskussion über getAll erneut zu beginnen.

Außerdem hat fetch die Antwort gefiltert, wo einige Header ausgeblendet sind. Was nicht dazu führt, dass ein voll ausgestatteter HTTP-Client per Spezifikation abgerufen wird.

Aus Entwicklungssicht ist die Einführung von nativem Fetch keine gute Idee. Und Leistung ist nicht wirklich ein Argument dafür.

Aber die Unterstützung der gleichen API ( fetch ) für den Browser und das Backend auf die gleiche Weise (ohne externe Abhängigkeit) wäre ein Gewinn für das gesamte JS/TS-Ökosystem.

@gkatsanos , wir haben dies auf dem Mai/Juni-Gipfel besprochen – hier ist, was auf https://docs.google.com/document/d/1tn_-0S_FG_sla81wFohi8Sc8YI5PJiTopEzSA7UaLKM/edit?usp=sharing blockiert wurde

Meiner Meinung nach wäre der wirkliche Gewinn für das Web, wenn der Knoten abgerufen werden sollte, tatsächlich, dass es plötzlich einen allgegenwärtigen Abbruchmechanismus über AbortSignal gibt. RxJS würde dies sofort nutzen. Andere Bibliotheken haben bereits damit begonnen, es zu verwenden.

Würde das auch lieben.

Ich mag es nicht, Browser und Knoten zu unterscheiden,
Das sind Ecmascript (oder sagen wir Javascript), die unten von C++ stammen, genau wie diese Babys von derselben Mutter sind. Ich mag es nicht, Babys kämpfen zu sehen. wir sollten ihnen die gleiche Liebe geben.
Egal welche API, wir können sie standardisieren.

Die Situation beim Einholen des Kerns hat sich nicht geändert. Es gibt viele, die es gerne hätten, aber es gibt eine Reihe von sehr nicht trivialen technischen Herausforderungen, die es schwierig machen, nicht zuletzt die Tatsache, dass, um mit der Implementierung in Browsern kompatibel zu sein, Core zuerst benötigt würde eine Implementierung der Streams-API des Browsers, die (in vielerlei Hinsicht) mit den vorhandenen Streams des Kerns nicht kompatibel ist und von Grund auf implementiert werden müsste, um leistungsfähig zu sein. Es gibt auch Probleme mit der Art und Weise, wie Fetch den internen globalen Status verwendet – was in einem Browserprozess gut funktioniert, aber nicht so gut auf der Serverseite. Ja, es gibt Implementierungen wie node-fetch , die nahe kommen, aber nicht vollständig spezifikationskonform sind (z. B. werden stattdessen Node.js-Streams verwendet). Dies sind natürlich keine unmöglich zu lösenden Probleme, sie brauchen nur jemanden, der bereit ist, die Zeit und Mühe in die Implementierung zu investieren und es durch den Prozess zu führen, um gelandet zu werden. Obwohl ich persönlich keine Notwendigkeit sehe, den Kern einzuholen, arbeite ich gerne mit jedem zusammen, der bereit ist, Zeit zu investieren.

Wenn jemand das abholen möchte: https://github.com/nodejs/node/pull/22352

Dies sind natürlich keine unmöglich zu lösenden Probleme, sie brauchen nur jemanden, der bereit ist, die Zeit und Mühe in die Implementierung zu investieren und es durch den Prozess zu führen, um gelandet zu werden.

Ich denke, ein guter erster Schritt wäre, nur Teile von Fetch hineinzubekommen, nämlich:

  • EventTarget (oder eine EventTarget-kompatible API)
  • AbortController ( https://github.com/openjs-foundation/summit/issues/273 btw )
  • Schließlich: holen

Ich denke, Streams können über Symbol.asyncIterator gehandhabt werden - das Ziehen von whatwg-Streams in den Kern wäre ein riesiges Unterfangen und müsste sehr sorgfältig durchgeführt werden.

Ich bin begeistert von EventTarget und AbortController im Node-Kern, die wie wichtige Schritte auf dem Weg scheinen, aber es gibt noch einige mehr.

@mcollina hat einen Plan formuliert, um WHATWG-Streams schließlich in den Kern zu verschieben, basierend auf der Zusammenarbeit mit asynchronen Iteratoren und dem Prototyping in einem Benutzermodul. Ich bin optimistisch, dass dies möglich sein wird, wenn sich jemand anstrengt! Ich sehe dies als eine erreichbare Voraussetzung für den Abruf im Kern, zusätzlich zu dem, was @benjamingr erwähnt, wenn die Kompatibilität mit der Websemantik ein Ziel ist.

Ein weiterer möglicher Aspekt von „Fetch in Core“ (den @mcollina betont hat) ist eine Art „User-Agent-API“, um zu erklären, wie Dinge wie Cookies, Caching und möglicherweise Proxying funktionieren würden. Die Abruffähigkeit von Browsern basiert direkt auf einem eingebauten Benutzeragenten, ohne volle Fähigkeiten, ihn zu manipulieren, z. B. das Wechseln zwischen verschiedenen Profilen. Für Serverumgebungen kann etwas mehr erforderlich sein.

Ich denke, beides ist machbar, wenn jemand in der Lage ist, die (große Menge) Arbeit zu leisten. Mein Kollege @ptomato in Igalia startet mit AbortController, basierend auf Sponsoring von Bloomberg, siehe https://github.com/nodejs/node/issues/31971.

Ich freue mich besonders über die WHATWG-Streams, die im Core landen! Danke an alle, die an all diesen Dingen arbeiten.

  1. Ich bin auch gespannt, also können wir eine Roadmap haben?
  2. Übrigens, bitte trennen Sie von Anfang an nicht Browser (oder so ähnlich) und Server-API für dieselbe Funktion! das sind nur ein "Benutzeragent". Kunden ist es egal, welchen Browser, welchen Server, welche API Sie verwenden.
  3. Ich möchte wirklich etwas beitragen, aber ich schreibe kein C++, können Sie es mir beibringen?

Ein weiterer möglicher Aspekt von „Fetch in Core“ ist eine Art „User-Agent-API“, um zu erklären, wie Dinge wie Cookies, Caching und möglicherweise Proxying funktionieren würden. Die Fetch-Fähigkeit von Browsern unterstützt dies direkt, ohne volle Manipulationsmöglichkeiten, z. B. das Wechseln zwischen verschiedenen Profilen. Für Serverumgebungen kann etwas mehr erforderlich sein.

Ist eigentlich der Punkt, auf den ich mich am meisten freue, damit ich sehen kann, ob ich den Ansatz für unsere CMS-Skriptsprache kopieren kann.

Ein Agent könnte auch der Punkt sein, an dem Sie entscheiden würden, wie die HTTP-Authentifizierung gehandhabt wird (was der Browser auch nativ für z. B. Basic http auth tun würde) und vielleicht sogar, wie und ob HTTP-Verbindungen wiederverwendet werden (erforderlich für die NTLM-Authentifizierung, die bei der Verbindung funktioniert). Stufe).

@jakearchibald langsam :] Zuerst AbortController, es müsste eine erhebliche Menge an Arbeit geleistet werden, bevor whatwg-streams im Kern landen. Vermutlich würde fetch mit async-Iterator-Unterstützung und nicht mit whatwg-Streams landen.

Für diejenigen, die daran arbeiten möchten, darf ich die folgende Strategie vorschlagen, die ich für die Entwicklung anderer großer neuer Funktionen verwendet habe:

  1. Erstellen Sie einen separaten Fork von nodejs/node (wie ich es sowohl für die http2- als auch für die quic-Arbeit getan habe ... z. B. https://github.com/nodejs/quic) und führen Sie die Arbeit an der Funktion dort isoliert durch. Dadurch können die Arbeiten viel schneller voranschreiten. Sobald wichtige Meilensteine ​​erreicht sind, öffnen Sie PRs, um diese Dinge mit dem Kern zusammenzuführen.

  2. Sei geduldig. Wenn es an der Zeit ist, diese PRs zu öffnen, um Dinge in den Kern zusammenzuführen, kann es viele Rückmeldungen/Diskussionen/Änderungswünsche geben. Diese können einige Zeit in Anspruch nehmen, insbesondere bei großen Änderungen.

  3. Lassen Sie die Möglichkeit des Vendoring in bestehenden Abhängigkeiten nicht unberücksichtigt. Wir müssen vielleicht nicht alles von Grund auf neu schreiben. Die Hauptgründe, warum wir etwas von Grund auf neu schreiben möchten, sind (a) wenn wir eine deutlich bessere Leistung erzielen können, (b) um eine größere Parität und Konsistenz mit der vorhandenen Node.js-API zu erreichen oder (c) um eine bessere Spezifikationskonformität zu erreichen.

  4. Denken Sie daran, dass das Hinzufügen eines neuen Top-Level-Moduls oder eines globalen Moduls in Node.js immer semver-major ist und dass alles, was hier getan wird, für einige Zeit experimentellen Status haben wird. Obwohl experimentelle Features nicht denselben Semver-Regeln unterliegen, ist der PR, der das anfängliche Feature hinzufügt, immer noch entweder Semver-Minor oder Semver-Major, je nachdem, wie es gemacht wird, es sei denn, das Feature befindet sich hinter einem Kompilier- oder Laufzeit-Flag. Dies ist wichtig, da Semver-Major-Adds, selbst experimentelle, nicht auf ältere Versionen zurückportiert werden können, es sei denn, diese Backports werden auf Semver-Minor-Weise durchgeführt (z. B. können wir kein neues Top-Level-Modul oder Global zu 13.x, 12.x , oder 10.x). Dies ist wichtig, da Dinge wie fetch und AbortController globale Werte im Browser sind und das Hinzufügen als globale Werte in Node.js sehr wichtig wäre.

  5. Der Schwerpunkt für die Node.js-Implementierung sollte immer darauf liegen, die Standardspezifikation und Kompatibilität so genau wie möglich einzuhalten. Wir sollten die Anzahl der Node.js-spezifischen Details, die Entwickler im Auge behalten müssen, unbedingt minimieren (d. h. das „So funktioniert es in Browsern, aber anders in Node.js“) ohne solide Begründung minimieren. Im Zweifelsfall sollte es sich an die Spezifikation halten.

4. Denken Sie daran, dass das Hinzufügen eines neuen Top-Level-Moduls oder eines globalen Moduls in Node.js _immer_ semver-major ist

Bedeutet das, dass V8-Updates, die neue Globals hinzufügen, immer Semver-Major sind und nicht zurückportiert werden können?

Übrigens, bitte trennen Sie von Anfang an nicht Browser (oder so ähnlich) und Server-API für dieselbe Funktion! das sind nur ein "Benutzeragent". Kunden ist es egal, welchen Browser, welchen Server, welche API Sie verwenden.

Ich möchte wirklich etwas beitragen, aber ich schreibe kein C++, können Sie es mir beibringen?

Wir können Ihnen C++ nicht beibringen, aber es gibt viele Orte, an denen Sie einen Beitrag leisten können, um sich den Kern, viele Recherchen und JavaScript-Aufgaben anzueignen.

Sie sind herzlich eingeladen, sich zu beteiligen (es gibt eine Sitzung im Gipfel zu AbortController in core) und sich über die letzte Sitzung zu informieren https://docs.google.com/document/d/1tn_-0S_FG_sla81wFohi8Sc8YI5PJiTopEzSA7UaLKM/edit?disco= AAAAGdykWVg&usp_dm=true&ts=5eaa5dc3

Bedeutet das, dass V8-Updates, die neue Globals hinzufügen, immer Semver-Major sind und nicht zurückportiert werden können?

Das ist, um ehrlich zu sein, eine totale Grauzone :-) ... insbesondere Node.js -Änderungen, die neue Globals hinzufügen, sind immer Semver-Major

Ich möchte wirklich etwas beitragen, aber ich schreibe kein C++, können Sie es mir beibringen?

In Bezug auf das Abrufen sollte es wirklich keinen Grund geben, c ++ anzufassen, da die gesamte API auf der JavaScript-Ebene vorhanden sein kann. Tatsächlich muss eine ordnungsgemäße Implementierung im Kern die http/1-, http/2- und schließlich http/3-APIs umfassen und abstrahieren, um konsistent und korrekt zu funktionieren – die alle auf der JavaScript-Ebene verfügbar gemacht werden.

Ich denke, wir könnten ein neues Modul oder ein neues globales Modul in bestehende Release-Zeilen zurückportieren, wenn dafür ein Befehlszeilen-Flag aktiviert werden muss

Ein weiterer möglicher Aspekt von „Fetch in Core“ (den @mcollina betont hat) ist eine Art „User-Agent-API“, um zu erklären, wie Dinge wie Cookies, Caching und möglicherweise Proxying funktionieren würden. Die Abruffähigkeit von Browsern basiert direkt auf einem eingebauten Benutzeragenten, ohne volle Fähigkeiten, ihn zu manipulieren, z. B. das Wechseln zwischen verschiedenen Profilen. Für Serverumgebungen kann etwas mehr erforderlich sein.

Im Wesentlichen ist dies mein Haupteinwand gegen einen vollständig spezifikationskonformen Abruf in den Kern. Wir können etwas "Fetch-ähnliches" implementieren, aber die Caching- und Sicherheitsteile davon sind extrem schwierig und möglicherweise nicht einmal auf der Serverseite erwünscht. Oder möglicherweise sind sie es, aber sie benötigen eine andere API, um verfügbar gemacht zu werden.

Um das oben Gesagte noch einmal zusammenzufassen: fetch() geht davon aus, dass es nur einen Benutzer für die gesamte JS-VM gibt. Node.js kann (und sollte) diese Annahme nicht treffen. node-fetch geht auch nicht davon aus und funktioniert deshalb sehr gut auf Node.js. Ich glaube nicht, dass wir in diesem Fall jemals spezifikationskonform sein könnten.

Wie ich bereits mehrfach sagte, bin ich bereit, jeden zu unterstützen, der bereit ist, diese große Anstrengung auf sich zu nehmen.

Offensichtlich haben Sie viele Worte. weil Sie etwas sagen, das nur auf bestehenden Standards basiert, und das nodejs-Team mehr Zusammenarbeit mit dem whatwg-Team benötigt. aus der Verlaufsansicht, zuerst Browser, dann Knoten. Knoten entsprechen von Anfang an nicht dem Webstandard, um API zu entwerfen, also haben Knoten große Schmerzen!

  1. Warum nicht auf unnötige Kompatibilität verzichten? @Jasnell
  2. Warum nicht den Fetch-Standard so umgestalten, dass er den Anwendungsfällen von Browsern und Knoten entspricht? @jakearchibald
  3. Warum nicht EventTarget implementieren?
  4. Ich überprüfe die Moduldokumente für Knoten http, https, http2, dass diese sagen, dass Knoten HTTP-Anforderungen/Antworten zwischenspeichern, warum Ihr Google-Dokument sagt, dass Knoten HTTP-Anforderungen/Antworten nicht zwischenspeichern

Kompatibilität ist nicht unnötig. Ohne sie gibt es keinen wirklichen Grund, dies überhaupt im Kern zu implementieren! Wir könnten die Benutzer einfach ihre eigenen verschiedenen inkompatiblen Versionen implementieren lassen. Da fetch in der Produktion verwendet wird, kann und will whatwg es nicht einfach umgestalten. Die Implementierung von EventTarget ist sinnvoll, aber es bleibt die Frage, ob wir dies tun sollten , da wir EventEmitter bereits haben.

Was das Caching betrifft, implementiert Node.js keinen Teil des HTTP-Cachings.

  1. Früher oder später sollte man auf Kompatibilität verzichten, da Knoten selbst eine LTS-Unterstützung haben.
  2. Haben Sie mit dem whatwg-Team kommuniziert?
  3. Aus der Knotenansicht ist der Implementierungsstandard einfacher als der Browser. Da der Knoten nur eine Laufzeitumgebung ist, nicht wie ein Browser, sind Kunden nicht immer bereit, ihren Browser zu aktualisieren!
  4. EventEmitter ist nicht so erstaunlich, aber unnötig im Vergleich zu EventTarget.

Dies ist ein Legacy-Problem im Verlauf des Knotens selbst. weil Knoten nicht von Anfang an dem Standard entsprechen, um API zu entwerfen.

Viele der Leute, die an node.js arbeiten, sind auch in Standardisierungsgremien involviert, einschließlich WHATWG. Bei diesem Problem geht es um das Hinzufügen von Abrufen, nicht um eine zufällige HTTP-API. Daher halte ich es für sinnvoll, die Diskussion hier auf konformes Abrufen zu beschränken.

Wenn Sie darüber nachdenken, existiert das großartige request -Paket nur, weil die Verwendung des integrierten HTTP-Moduls zu viele Boilerplates erforderte. Betrachten wir es auch so:

  • Browser: XMLHttpRequest -> fetch
  • Node.js: http/https/http2 -> abrufen?

Die Abruf-API wurde entwickelt, um Webanfragen im Browser einfacher zu stellen und ersetzte XMLHTTPRequest . Dieselbe API sollte als Ersatz für http , https und http2 in Node.js verwendet werden.

@Richienb

Die Abruf-API wurde als einfachere Möglichkeit zum Erstellen von Webanforderungen im Browser erstellt, die als Ersatz für XMLHTTPRequest kam

Tatsächlich wurde IIUC fetch als _API auf niedrigerer Ebene_ in Browsern mit _mehr Fähigkeiten_ erstellt und nicht als eine API auf höherer Ebene, die ergonomisch ist. Fetch macht es einfach, Antworten zu streamen und Dinge auf niedriger Ebene wie das in Node integrierte HTTP zu erledigen.

Wenn Sie zum Fetch-Repo gehen und die Diskussionen lesen, wird die Tatsache, dass es sich bei Fetch um eine moderne API mit Fähigkeiten und nicht um syntaktischen Zucker handelt, sehr deutlich gemacht.

@benjamingr Du hast hier deinen eigenen Fall unterstützt. Nach Ihrer Erklärung ist window.fetch eine moderne Low-Level-API für Browser, die mehr Funktionen als XMLHTTPRequest hat. Dies gilt auch für Node.

Nehmen Sie beispielsweise die Option redirect: 'follow' in der window.fetch-API. In Node.js benötigen Sie https://www.npmjs.com/package/follow-redirects , was dies ermöglicht.

@Richienb um es klar zu sagen - ich bin nicht gegen das Abrufen im Kern - ich sage nur, dass Abrufen in der Vergangenheit nicht zu Browsern hinzugefügt wurde, weil es sich um eine höhere Ebene handelte - es wurde hinzugefügt, weil es sich um eine _niedrigere Ebene_ handelte.

Umleitungen unterscheiden sich zwischen Browsern und Node aufgrund des Agentenmodells und redirects: follow ist eigentlich eine _niedrigere API_ als das, was XHR hatte (immer Umleitungen folgen, das ist nicht konfigurierbar). Das HTTP von Node ist ebenfalls eine API auf niedriger Ebene, sodass es im Gegensatz zu XHR nicht immer Weiterleitungen folgt.


Um es klar zu sagen: Abrufen ist derzeit nur im Kern blockiert, weil es _viel Arbeit und Mühe_ ist, Kern gut hinzuzufügen, und es gibt zuerst viele Sprungbretter (wie herauszufinden, was mit AbortController- und WHATWG-Streams zu tun ist). Fetch ist im Kern nicht blockiert, weil wir es nicht im Kern wollen.

Was wir meiner Meinung nach vermeiden möchten, ist eine nicht konforme Deno-ähnliche Fetch-Situation, obwohl ich denke, dass die Zusammenarbeit mit Standardisierungsgremien uns einen guten Mittelweg bieten kann, wo wir eine Teilmenge von Fetch haben, die wirklich universell und sinnvoll ist. (Um es klar zu sagen, dies ist keine Respektlosigkeit gegenüber Deno, wo sie sich wirklich bemüht haben, eine Spezifikationsbeschwerde für serverseitiges JavaScript abzurufen, und mit der Spezifikation gegen eine Reihe von Wänden stoßen, die es sehr, sehr schwierig machen.)

Ich ermutige Sie, sich an einer dieser Bemühungen zu beteiligen – sie bewegen sich meistens langsam, weil sie sich viel Mühe geben und Priorität haben – dies ist keiner der Orte, an denen wir bei Meinungsverschiedenheiten festsitzen.

Kurzes Update: Wir haben jetzt experimentelle Unterstützung für EventTarget und AbortController in Master gelandet. In nicht allzu ferner Zukunft werde ich mich mit der Blob/File-API-Unterstützung und etwas mehr Grundlagen für WHATWG-Streams befassen. Ich weiß nicht, ob wir es bis zur Implementierung von fetch schaffen, aber wir sollten in der Lage sein, viele der erforderlichen Komponenten bereitzustellen.

deno ist großartig, aber es steht geschrieben von rust, dass die Syntax sehr schwierig ist, oh mein Gott. Ich hoffe, dass nodejs mehr und mehr ecmascript-Funktionen unterstützt, oder nodejs wird veraltet sein und durch deno ersetzt. @jasnell wann soll die Funktion EventTarget und AbortController veröffentlicht werden?

Ich weiß nicht, ob wir es bis zur Implementierung von fetch schaffen, aber wir sollten in der Lage sein, viele der erforderlichen Komponenten bereitzustellen.

Wie wäre es, wenn Sie nach einer Möglichkeit suchen, zur Abrufspezifikation beizutragen und nach einer API zu fragen, mit der wir benutzerdefinierte Typen zurückgeben und keine Whatwg-Streams (oder Verhandlungen) verwenden können?

@anlexN deno und node stehen nicht in Konflikt oder sind Feinde. Node sollte Funktionen hinzufügen, wenn es hilfreich, mitfühlend und gut für unsere Benutzer und die Gesundheit der Plattform ist.

Wenn überhaupt, hat uns die Tatsache, dass Deno Pionierarbeit bei einer mit EventTarget gebauten Plattform geleistet hat, geholfen, EventTarget hinzuzufügen, ebenso wie Promises und AbortController.

Nehmen wir nicht ein Ökosystem mit mehr als einem Projekt, das IMO ein Netto-Positives ist, als etwas anderes (ein Netto-Positives).

Ich denke, der beste Weg, mit Streams umzugehen, besteht darin, irgendwann (in langer Zeit) vollständig auf Whatwg-Streams von Node-Streams umzusteigen, aber ich denke, im Moment sollte die Implementierung als global ein guter Schritt nach vorne sein.

Die meisten Leute konzentrieren sich weiterhin auf APIs und Streams. APIs und Code sind die geringsten Probleme bei einem standardkonformen Abruf.

Ich glaube nicht, dass wir jemals einen konformen Abruf als global implementieren können, hauptsächlich weil die Spezifikation davon ausgeht, dass es nur einen Benutzer pro JS-Kontext gibt. Node.js als Serverlaufzeit unterstützt mehrere gleichzeitige Benutzer. Dies spiegelt sich in so vielen kritischen Teilen der Spezifikation wider, wie dem Sicherheitsmodell, dem Caching, dem Umgang mit Cookies, dem Umgang mit Keep-Alive-Sockets, dem Umgang mit HTTP/1.1 gegenüber HTTP/2 und in Zukunft HTTP/3. Im Wesentlichen ist fetch _low level_ für die Browser, aber _high level_ für Node.js.

Die Lösung dieser Probleme ist eine __erhebliche Menge an Arbeit__ und bisher war niemand bereit, sie zu sponsern: Ich schätze, dass es für einen Ingenieur, der sich mit Standards auskennt, 3-6 Monate dauern wird, etwas Experimentelles zu machen, und wahrscheinlich weitere 6-12 Monate Standardarbeit, um eine Spezifikation darüber zu haben, wie ein "serverseitiger Abruf" aussieht.

Das Hauptproblem ist, dass node-fetch das Problem wirklich gut löst und es _keinen wahrgenommenen Nutzen_ gibt, der den Entwicklungsaufwand rechtfertigt.

Ich helfe ein bisschen mit node-fetch aus, ich weiß, dass viele Komponenten damit zu tun haben, also wird es höchstwahrscheinlich noch ein bisschen länger bleiben, bevor der Knotenkern es bekommt. Uns zunächst Zugang zu kleineren Komponenten zu verschaffen, wird langfristig helfen

Eine Art Abhängigkeitsbaum von der niedrigsten zur höheren Komponente:

  • Blob+BlobSpeicher

    • Dateien



      • Formulardaten



    • Ereignisziel

    • Controller abbrechen

    • Signal abbrechen



      • Whatwg-Streams



    • Header (denken Sie, dies könnte eine separate Sache sein, die mit anderen Bibliotheken und sogar http (s) funktionieren könnte)

Mein persönliches Ziel ist es wirklich nicht, fetch selbst im Kern zu implementieren, sondern die Bestandteile zu implementieren, damit eine Userland-Implementierung besser wird, insbesondere wenn diese Teile effektiv für andere Zwecke im Kern verwendet werden können. Bei EventTarget und AbortController fange ich an, aber sobald ich mit ein paar anderen Punkten auf meiner Todo-Liste ein bisschen weiter bin, plane ich, mir die Blob- und Datei-APIs anzusehen ... nicht zuletzt, weil ich Blob und glaube File kann verwendet werden, um die Leistung in anderen Bereichen zu steigern (respondWithFile-APIs). In dieser Hinsicht gibt es viel zu tun.

Ist es möglich, die Chromium-Implementierung zu nehmen und sie dann mit dem Knoten zu verbinden?

@wood1986 aufgrund der oben beschriebenen Caching- und "Agentur" -Probleme wahrscheinlich nicht. Der Chrome-HTTP-Stack und die Fetch-Implementierung enthalten viel Logik, die Node nicht wiederverwenden kann (aus Sicherheitsgründen, zur Begrenzung der Parallelität pro Host und zum Caching), und sie ist auch intern eng gekoppelt, und wenn sie keine signifikante Umgestaltung vornehmen, sehe ich keine Möglichkeit, sie zu teilen dieser Code.

Ich denke, es wäre großartig, wenn umgebungsdefinierter Proxy in der zukünftigen Kern- fetch -API unterstützt werden könnte. Es gibt sicherlich eine beträchtliche Nachfrage nach dieser Funktion, und Node scheint die einzige große serverseitige „Sprache“ zu sein, die keine solche integrierte Unterstützung bietet.

Hallo zusammen, basierend auf den obigen Kommentaren habe ich das Gefühl, dass fetch im Knotenkern aufgrund des Arbeitsaufwands und der technischen Herausforderungen immer noch eine Melodie der fernen Zukunft ist.

Ich möchte einen Datenpunkt auf hoher Ebene von meiner Seite und vielleicht eine neue (nicht sichere) Perspektive bereitstellen. Es geht nicht nur um fetch , sondern um Networking im Allgemeinen. (Entschuldigung, wenn Sie meinen Kommentar off-topic finden und solche Diskussionen zwangsläufig schon einmal stattgefunden haben).

Es gibt meiner Meinung nach zwei Hauptverwendungen von nodejs in freier Wildbahn:

1) Produktionsserver mit hohem Datenverkehr
2) Erstellen Sie Toolketten von Front-End-JS-Entwicklern, Befehlszeilentools und Code-Snippets

Ich habe das Gefühl, dass sich die meisten Hauptbeitragenden, die hier diskutieren, ausschließlich auf Anwendungsfall 1) konzentrieren. (vielleicht bin ich falsch)
Ich persönlich benutze node seit gut einem Jahrzehnt hauptsächlich für Anwendungsfall 2).

Wenn es um Produktionsserver geht, können Entwickler http Module oder kampferprobte Bibliotheken verwenden, es macht keinen großen Unterschied, weil _Sie sowieso viel Code haben und auch viele npm-Deps._ Ich auch stimme dem "Keep Core Small"-Gefühl zu.

Aber wenn es um Kommandozeilen-Tools geht, ist es meiner Meinung nach _höchst_ wünschenswert, eine einfache Möglichkeit zu haben, HTTP GET in einer Codezeile _abhängigkeitslos_ auszuführen. Mal sehen, was andere Programmiersprachen bieten:

gehen: http.Get("https://example.com/")
python3: urllib.request.urlopen("https://example.com/").read()
php: file_get_contents("https://example.com/")

Ich verwende keine dieser Sprachen täglich, und wahrscheinlich haben diese APIs Grenzen und Fallstricke, aber
Sie können wahrscheinlich zugeben, dass die APIs wirklich einfach und leicht zu merken aussehen.

Wohingegen eine ähnliche Vorgehensweise im Knoten mit http / https das Kopieren und Einfügen einer beträchtlichen Boilerplate erfordert, und ehrlich gesagt, es ist ziemlich frustrierend.

IMO, selbst wenn es nicht möglich ist, spezifikationskonforme fetch in Knoten zu implementieren, oder es ein langer Weg ist, es zu haben, wäre etwas anderes (auch wenn sehr begrenzt) immer noch wünschenswert.

(Trotzdem verstehe ich voll und ganz, dass es nicht möglich ist, ein Feature auszuliefern und den Leuten zu sagen, "nicht auf Prod-Servern zu verwenden", weil die Leute in dem Moment, in dem es da ist, anfangen werden, es zu missbrauchen).

Ich würde gerne eines Tages etwas Ähnliches wie das unten stehende Snippet mit node machen (es funktioniert mit Browsern) und es in meinen schnellen Wegwerfskripten, PoCs, Aliasen usw. verwenden.

node -p "(await (await fetch('https://api.example.com/stuff')).json()).list.map(o => o.id).join(',')"

ohne das Sternchen "remember to npm install some-package" hinzufügen zu müssen.

Die knappe Art, HTTP-Aufrufe durchzuführen, erleichtert das Experimentieren, das Teilen von Code über Slack, in Dokumentationsstücken usw.
Der Mehrwert überwiegt meiner Meinung nach die "Keep Core Small"-Regel.

Einige abschließende Punkte: die Funktionen wie:

  • API-weise Ähnlichkeit mit fetch ,
  • Glocken und Pfeifen wie das Akzeptieren von Objekten als Param, URL-Kodierung,
  • Unterstützung für Streaming,

usw. sind alle nice to have, aber (IMO) nicht notwendig. Ein wirklich einfacher und begrenzter Convenience-Wrapper über http(s) würde wirklich einen langen Weg zurücklegen.

Ich bin im Allgemeinen +1, um so etwas hinzuzufügen.

Ich denke, wir sind kurz davor, fetch-without-streams-and-security-rules in Bezug auf den benötigten Code zu landen (mit AbortController und EventTarget und ohne Streams).

Ich bin dafür, node-fetch-without-streams-or-node-streams für die erste Iteration zu machen und Streams später hinzuzufügen.

Ich möchte, dass fetch irgendwann "echter Whatwg-Fetch" ist und nicht "etwas namens Fetch, aber völlig anders".

Ich möchte sagen, dass wir immer noch entscheiden können, http/promises zusätzlich zu oder anstelle von fetch zu machen und keine Whatwg-Streams usw. implementieren müssen. Ich stimme auch https://github.com/ zu.

Ich denke, wir sind kurz davor, fetch-without-streams-and-security-rules zu landen

Ich bin dafür, Knotenabruf ohne Streams oder Knotenstreams für die erste Iteration durchzuführen und Streams später hinzuzufügen.

Ich denke, eine niedrigere Ebene eines asynchronen Iterators oder eines Knotenstroms wäre besser als nichts, selbst wenn er sich nicht in derselben Spur wie die Spezifikation befindet.
Dann könnten Sie entweder stream.Readable.from(iterable) oder whatwg.ReadableStream.from(iterable) tun oder einfach nur:

for await (let chunk of res.body) { ... }

Dieser Code würde für jede Art von Körper funktionieren - ob es sich um einen asynchron iterierbaren, einen Knotenstrom oder einen Whatwg-Stream handelt, da sich alles gleich verhält, wenn es darum geht, asynchron iterierbar zu sein und uint8arrays zu liefern.

Ich würde lieber eine niedrigere Ebene von nur einer einfacheren asynchronen Iterable bevorzugen, wenn whatwg streams zu weit entfernt erscheint. Dann hätten Sie immer noch die Vorteile, große Körper mit Fetch zu produzieren und zu konsumieren.
ofc eine Konsolenwarnung könnte nützlich sein, um Iteratoren zu verwenden (und den Benutzer wissen zu lassen, dass wir noch keine echten Streams unterstützen) und möglicherweise veraltete Iteratoren später, wenn/falls whatwg-Streams in node. Ich denke, die Umwandlung eines Iterators in einen Stream ist mit nur x.from(iterable) sehr einfach

Aber ich bin mit node-fetch-without-streams-or-node-streams und fetch-without-streams-and-security-rules einverstanden, es ist eine gute erste Iteration - irgendwo muss man anfangen.

Aber ich denke auch, dass es eine gute Sache sein könnte, während einer Übergangszeit sowohl Whatwg-Streams als auch Node-Streams zu unterstützen, um mit beiden zu arbeiten, und beide einfach als asynchronen Iterator zu behandeln, da sie bei Verwendung von async iterator + dort auf die gleiche Weise verwendet werden können Es gibt immer noch viele eingebaute Node-APIs, die Node-Streams verwenden.

Ich möchte sagen, dass wir immer noch entscheiden können, http/promises zusätzlich zu oder anstelle von fetch zu machen und keine whatwg-Streams usw. implementieren müssen. Ich stimme auch #19393 (Kommentar) zu.

Wie diese Idee wäre es auch cool, wenn http einige fetch-ähnliche Methoden wie .text() , .json() und .arrayBuffer() hinzugefügt hätte, um damit zu beginnen. aber ich möchte immer noch Whatwg-Streams im Knoten

Die erste Implementierung sollte streng kompatibel mit den bestehenden Promise-basierten APIs sein, später können wir sie mit fortgeschritteneren Dingen wie Iterator/Stream erweitern (hoffentlich auf standardisierte Weise).

Meiner Meinung nach kann das Abrufen intern erstellt werden, es ist jedoch am besten für den Knoten. Als node.js-Entwickler ist es mir egal, ob fetch intern Streams verwendet oder was auch immer. Es ist mir auch egal, ob es ganz anders aufgebaut ist als window.fetch().

Stattdessen ist das EINZIGE, was mich als node.js-Entwickler interessiert, dass es genau die gleiche API und das gleiche API-Verhalten wie die window.fetch() -API hat.

Beispiel: Ich möchte fetch und seine versprochene API verwenden, genau wie window.fetch() oder node-fetch. Aber es ist mir egal, wie intern das Promise aufgelöst wird, dh innerhalb eines Streams, eines Events, eines Callbacks oder was auch immer.

Manchmal klingt es hier so, als müsste eine Fetch-API in node.js genauso „funktionieren“, wie die originale Fetch-Api. Aber ich glaube nicht, dass das stimmt. Es muss die gleichen Dinge „tun“, sich gleich „verhalten“ und es sollte genau die gleiche API „haben“, aber auf keinen Fall muss es genau gleich „funktionieren“.

Nach meiner Meinung.

@MBODM

genau das gleiche API und API-Verhalten

Aus diesem Grund ist die Implementierung von Fetch in Node.js eine Herausforderung. Es gibt viel Kontext in dieser Ausgabe, warum.

@bnb beachten Sie, dass sie erwähnen, dass node-fetch und window.fetch dieselbe API haben, was die Idee bestätigt, dass _wir nicht spezifikationskonform sein müssen_.

Ich möchte die Wunde nicht noch mehr salzen, aber ja, für viele von uns erledigt node-fetch aus unserer Sicht den Job, es ist vielleicht nicht perfekt, aber es tut es.

Persönlich hätte ich nichts dagegen, wenn fetch Einschränkungen hat und den Browserspezifikationen folgt, während das Modul http es Ihnen ermöglicht, komplexere Situationen zu implementieren und mehr Kontrolle über die Netzwerksituation zu haben, als Sie vielleicht haben verfügen über.

Im schlimmsten Fall müssen wir uns in unserer Anwendungsschicht mit den Unterschieden zwischen den einzelnen Implementierungen auseinandersetzen, wenn wir eine einzelne API haben wollen, die den HTTP-Client tauscht 🤷🏻

Wie wir es heute mit isomorphic-fetch oder einem anderen dieser Pakete tun, bitten wir nur um etwas Unterstützung von den Hauptmitwirkenden und um unser Leben einfacher zu machen mit Abstraktionen, die sich definitiv auszahlen.

Ich hatte zuvor vorgeschlagen, node-fetch in node einzubetten und als http.fetch verfügbar zu machen.

Es könnte sich lohnen, diese Idee weiter zu untersuchen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen