diff --git a/src/content/docs/de/4x/guide/debugging.mdx b/src/content/docs/de/4x/guide/debugging.mdx index ee9bf34278..5c60014858 100644 --- a/src/content/docs/de/4x/guide/debugging.mdx +++ b/src/content/docs/de/4x/guide/debugging.mdx @@ -4,6 +4,7 @@ description: Erfahren Sie, wie Sie Debugging-Logs in Express.js-Anwendungen akti --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; Um alle internen Logs zu sehen, die in Express verwendet werden, setzen Sie die Umgebungsvariable `DEBUG` auf `express:*` beim Starten Ihrer App. @@ -86,22 +87,119 @@ Wenn eine Anfrage an die App gestellt wird, sehen Sie die im Express-Code angege Um die Protokolle nur von der Router-Implementierung zu sehen, setzen Sie den Wert `DEBUG` auf `express:router`. Um Protokolle nur von der Anwendungsimplementierung zu sehen, setzten Sie den Wert von `DEBUG` auf `express:application`, und so weiter. -## Anwendungen generiert von `Express` +## Using `debug` in your own code -Eine Anwendung, die durch den Befehl `express generiert` erzeugt wird, benutzt das Modul `debug` und sein Debug-Namensraum wird auf den Namen der Anwendung übertragen. +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: -Wenn Sie zum Beispiel die App mit `$ express Beispiel-App` erstellt haben, können Sie die Debug-Anweisungen mit folgendem Befehl aktivieren: + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; + +const debug = debugModule('myapp:server'); +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` Sie können mehr als einen Debug-Namensraum angeben, indem Sie eine kommaseparierte Namensliste zuweisen: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,express:router node index.js +``` + +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*" } +} ``` +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Erweiterte Optionen Wenn Sie über Node.js laufen, können Sie ein paar Umgebungsvariablen festlegen, die das Verhalten der Debug-Protokollierung ändern: diff --git a/src/content/docs/de/4x/guide/error-handling.mdx b/src/content/docs/de/4x/guide/error-handling.mdx index 22da5d53fc..c03549c435 100644 --- a/src/content/docs/de/4x/guide/error-handling.mdx +++ b/src/content/docs/de/4x/guide/error-handling.mdx @@ -62,14 +62,16 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Starting with Express 5, route handlers and middleware that return a Promise -will call `next(value)` automatically when they reject or throw an error. -Zum Beispiel: +Errors from rejected promises are not passed to `next` automatically, and this includes `async` functions: if an `async` route handler throws or awaits a rejected promise, the rejection is unhandled, which crashes the process on current Node.js versions. You must catch the error yourself and pass it to Express: ```js app.get('/user/:id', async (req, res, next) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` @@ -77,14 +79,22 @@ app.get('/user/:id', async (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` -Wenn `getUserById` einen Fehler oder eine Ablehnung, wird `next` entweder mit -dem Wurffehler oder dem abgelehnten Wert aufgerufen. Wenn kein abgelehnter Wert angegeben wird, wird `next` -mit einem Standard-Fehlerobjekt aufgerufen, das vom Express-Router bereitgestellt wird. + + +Consider [updating to Express 5](/guide/migrating-5), where route handlers and middleware that +return a Promise call `next(value)` automatically when they reject or throw an error, making the +`try...catch` above unnecessary. + + Wenn du etwas an die `next()` Funktion übergibt (außer den String `'route'`), Express betrachtet die aktuelle Anfrage als Fehler und überspringt alle @@ -180,9 +190,7 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Da Versprechungen automatisch sowohl synchrone Fehler als auch abgelehnte Versprechungen fangen, -du kannst einfach `next` angeben, da der letzte Catch Handler und Express Fehler fängt an -weil der Catch-Handler den Fehler als erstes Argument angibt. +If a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, passing `next` as the handler is enough: `.catch` calls it with the error as its first argument, which is exactly the argument `next` expects, so the error reaches Express. Sie können auch eine Kette von Handlern verwenden, um sich auf synchrone Fehler zu stützen, indem Sie den asynchronen Code auf etwas Triviales reduzieren. Zum Beispiel: @@ -219,8 +227,8 @@ app.get('/', [ ]); ``` -Das obige Beispiel hat ein paar triviale Anweisungen aus dem Aufruf `readFile` -. If `readFile` causes an error, then it passes the error to Express, otherwise you +The above example contains a couple of trivial statements following the `readFile` +call. If `readFile` causes an error, then it passes the error to Express, otherwise you quickly return to the world of synchronous error handling in the next handler in the chain. Dann versucht das obige Beispiel die Daten zu verarbeiten. Wenn dies fehlschlägt, fängt der Synchron-Fehlerhandler ihn ab. Hätten Sie diese Verarbeitung innerhalb von @@ -424,7 +432,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Auch in diesem Beispiel wird `clientErrorHandler` wie folgt definiert; in diesem Fall wird der Fehler explizit an den nächsten weitergegeben. -Beachten Sie, dass, wenn _not_ in einer Fehlerbehandlungsfunktion "Weiter" aufruft, Sie dafür verantwortlich sind, die Antwort zu schreiben (und zu beenden). Andernfalls werden diese Anträge "hängen" und sind nicht für die Müllsammlung berechtigt. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Andernfalls werden diese Anträge "hängen" und sind nicht für die Müllsammlung berechtigt. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/de/4x/guide/overriding-express-api.mdx b/src/content/docs/de/4x/guide/overriding-express-api.mdx index eddfc6a403..a3afb12be3 100644 --- a/src/content/docs/de/4x/guide/overriding-express-api.mdx +++ b/src/content/docs/de/4x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -Die Express API besteht aus verschiedenen Methoden und Eigenschaften auf den Anfrage- und Antwort-Objekten. Diese werden vom Prototyp geerbt. Es gibt zwei Erweiterungspunkte für die Express API: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. Diese werden vom Prototyp geerbt. Es gibt zwei Erweiterungspunkte für die Express API: 1. Die globalen Prototypen unter `express.request` und `express.response`. 2. App-spezifische Prototypen bei `app.request` und `app.response`. diff --git a/src/content/docs/de/4x/guide/routing.mdx b/src/content/docs/de/4x/guide/routing.mdx index 7228e3ff11..01cbd00fd3 100644 --- a/src/content/docs/de/4x/guide/routing.mdx +++ b/src/content/docs/de/4x/guide/routing.mdx @@ -9,11 +9,11 @@ _Routing_ bezieht sich darauf, wie die Endpunkte einer Anwendung (URIs) auf Kund Für eine Einführung in das Routing siehe [Basic routing](/starter/basic-routing). Du definierst Routing, indem du Methoden des Express `app` Objekts verwendest, die den HTTP-Methoden entsprechen; -zum Beispiel, `app. et()` um GET-Anfragen und `app.post` zu behandeln, um POST-Anfragen zu bearbeiten. For a full list, +zum Beispiel, `app.get()` um GET-Anfragen und `app.post` zu behandeln, um POST-Anfragen zu bearbeiten. For a full list, see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. Mit anderen Worten, die Anwendung "lauscht" für Anforderungen, die mit der angegebenen Route(s) und Methode(n) übereinstimmen und wenn es ein Spiel erkennt, ruft es die angegebene Callback-Funktion auf. +Mit anderen Worten, die Anwendung "lauscht" für Anforderungen, die mit der angegebenen Route(s) und Methode(n) übereinstimmen und wenn es ein Spiel erkennt, ruft es die angegebene Callback-Funktion auf. Mit anderen Worten, die Anwendung "lauscht" für Anforderungen, die mit der angegebenen Route(s) und Methode(n) übereinstimmen und wenn es ein Spiel erkennt, ruft es die angegebene Callback-Funktion auf. In der Tat können die Routing-Methoden mehr als eine Callback-Funktion als Argumente haben. Mit mehreren Callback-Funktionen, es ist wichtig, `next` als Argument für die Callback-Funktion zur Verfügung zu stellen und dann `next()` im Körper der Funktion aufzurufen, um die Steuerung @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express unterstützt Methoden, die allen HTTP-Anfragemethoden entsprechen: `get`, `post` und so weiter. For a full list, see [app.METHOD](/api/application#appmethod). -Es gibt eine spezielle Routing-Methode, `app.all()`, die benutzt wird, um Middleware-Funktionen an einem Pfad für _all_ HTTP-Requestmethoden zu laden. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +Es gibt eine spezielle Routing-Methode, `app.all()`, die benutzt wird, um Middleware-Funktionen an einem Pfad für _all_ HTTP-Requestmethoden zu laden. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Routenpfade -Routenpfade in Kombination mit einer Anfragemethode definieren die Endpunkte, an denen Anfragen gestellt werden können. Routenpfade können Zeichenketten, Zeichenkettenmuster oder reguläre Ausdrücke sein. +Routenpfade in Kombination mit einer Anfragemethode definieren die Endpunkte, an denen Anfragen gestellt werden können. Routenpfade können Zeichenketten, Zeichenkettenmuster oder reguläre Ausdrücke sein. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -235,6 +235,26 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => { }); ``` +A wildcard (`*`) on its own matches anything at its position, including entire subpaths. For example, this route path will match `/file/style.css` as well as `/file/javascripts/jquery.js`. Wildcards are unnamed, so the matched value is available as `req.params[0]` instead of a named parameter. + +```js +app.get('/file/*', (req, res) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/file/*', (req: Request, res: Response) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + ### Routenpfade basierend auf regulären Ausdrücken @@ -348,6 +368,14 @@ Zeichen mit einem zusätzlichen Backslash maskieren, zum Beispiel `\d+`. The [`*`](https://github.com/expressjs/express/issues/2495) character in regular expressions is not interpreted in the usual way. Benutze `{0,}` anstelle von `*`. +Unlike named route parameters, wildcard (`*`) matches in [string patterns](#route-paths-based-on-string-patterns) and capture groups in regular expressions are unnamed: their values are available by position, as `req.params[0]`, `req.params[1]`, and so on. + +``` +Route path: /file/*/size/* +Request URL: http://localhost:3000/file/javascripts/jquery.js/size/large +req.params: { "0": "javascripts/jquery.js", "1": "large" } +``` + ## Routenhandler Du kannst mehrere Callback-Funktionen bereitstellen, die sich wie [middleware](/guide/using-middleware) verhalten um eine Anfrage zu bearbeiten. Die einzige Ausnahme ist, dass diese Callbacks `next('route')` aufrufen könnten, um die restlichen Rufnummern zu umgehen. Sie können diesen Mechanismus nutzen, um Vorbedingungen auf einer Route aufzuerlegen, dann die Kontrolle an die nachfolgenden Routen übergeben, wenn es keinen Grund gibt, mit der aktuellen Route fortzufahren. @@ -387,7 +415,7 @@ In diesem Beispiel: Routenhandler können in Form einer Funktion, eines Arrays von Funktionen oder Kombinationen beider sein, wie in den folgenden Beispielen gezeigt. -Eine einzelne Callback-Funktion kann eine Route handhaben. Zum Beispiel: +Mehr als eine Callback-Funktion kann eine Route handhaben (stelle sicher, dass du das `next` Objekt angibst). Zum Beispiel: ```js app.get('/example/a', (req, res) => { @@ -403,7 +431,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -Mehr als eine Callback-Funktion kann eine Route handhaben (stelle sicher, dass du das `next` Objekt angibst). Zum Beispiel: +Eine Kombination aus unabhängigen Funktionen und Arrays von Funktionen kann eine Route handhaben. Zum Beispiel: ```js app.get( @@ -527,7 +555,7 @@ app.get( ## Antwortmethoden -Die Methoden auf dem Antwortobjekt (`res`) in der folgenden Tabelle können eine Antwort an den Client senden und den Request-Antwort-Zyklus beenden. Wenn keine dieser Methoden von einem Routenhandler aufgerufen wird, bleibt die Client-Anfrage hängen. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. Wenn keine dieser Methoden von einem Routenhandler aufgerufen wird, bleibt die Client-Anfrage hängen. | Methode | Beschreibung | | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------- | @@ -544,7 +572,7 @@ Die Methoden auf dem Antwortobjekt (`res`) in der folgenden Tabelle können eine ## app.route() Sie können verkettende Routenhandler für einen Routenpfad erstellen, indem Sie `app.route()` verwenden. -Da der Weg an einem einzigen Ort angegeben wird, ist die Schaffung modularer Routen hilfreich, ebenso wie die Reduzierung von Redundanz und Typos. Weitere Informationen über Routen finden Sie unter [Router() documentation](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router). Hier ist ein Beispiel für verkettete Routenhandler, die mit `app.route()` definiert werden. @@ -580,9 +608,9 @@ app ## express.Router -Verwende die Klasse `express.Router`, um modulare mountbare Routenhandler zu erstellen. Eine `Router`-Instanz ist ein komplettes Middleware- und Routing-System; aus diesem Grund wird sie oft als "Mini-App" bezeichnet. +Verwende die Klasse `express.Router`, um modulare mountbare Routenhandler zu erstellen. Eine `Router`-Instanz ist ein komplettes Middleware- und Routing-System; aus diesem Grund wird sie oft als "Mini-App" bezeichnet.The following example creates a router as a module, loads a middlew -Das folgende Beispiel erzeugt einen Router als Modul, lädt eine Middleware-Funktion darin definiert einige Routen und mountet das Router-Modul auf einem Pfad in der Hauptanwendung. +Das folgende Beispiel erzeugt einen Router als Modul, lädt eine Middleware-Funktion darin definiert einige Routen und mountet das Router-Modul auf einem Pfad in der Hauptanwendung.Create a router file named `birds.js` in the app directory, with th Erstelle eine Router-Datei namens `birds.js` im App-Verzeichnis, mit folgendem Inhalt: @@ -677,7 +705,7 @@ app.use('/birds', birds); Die App wird nun in der Lage sein, Anfragen an `/birds` und `/birds/about` zu bearbeiten, aufrufen sowie die Middleware-Funktion `timeLog` aufrufen, die spezifisch für die Route ist. -Aber wenn die übergeordnete Route `/birds` Pfadparameter hat, wird sie standardmäßig nicht von den Unterrouten aus erreichbar sein. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +Aber wenn die übergeordnete Route `/birds` Pfadparameter hat, wird sie standardmäßig nicht von den Unterrouten aus erreichbar sein. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter). ```js const router = express.Router({ mergeParams: true }); diff --git a/src/content/docs/de/4x/guide/using-middleware.mdx b/src/content/docs/de/4x/guide/using-middleware.mdx index 2e004911fa..157434348e 100644 --- a/src/content/docs/de/4x/guide/using-middleware.mdx +++ b/src/content/docs/de/4x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Lernen Sie, wie Sie Middleware in Express.js-Anwendungen verwenden, import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express ist ein Routing- und Middleware-Webframework mit minimaler Funktionalität: Eine Express-Anwendung ist im Wesentlichen eine Reihe von Middleware-Funktionsaufrufen. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -_Middleware_ Funktionen sind Funktionen, die Zugriff auf das [request object](/api#req) (`req`), das [Antwort-Objekt](/api#res) (`res`) und die nächste Middleware-Funktion im Request-Antwort-Zyklus der Anwendung. Die nächste Middleware-Funktion wird üblicherweise durch eine Variable namens `next` bezeichnet. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Middleware-Funktionen können folgende Aufgaben ausführen: - Führe jeden Code aus. -- Änderungen an der Anfrage und den Antwort-Objekten vornehmen. +- Modify the request and response objects. - Beende den Request-Antwort-Zyklus. -- Rufen Sie die nächste Middleware-Funktion im Stack auf. +- Pass control to the next middleware function. -Wenn die aktuelle Middleware-Funktion den Request-Antwort-Zyklus nicht beendet, muss sie `next()` aufrufen, um die Kontrolle an die nächste Middleware-Funktion zu übergeben. Andernfalls bleibt die Anfrage hängen. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Andernfalls bleibt die Anfrage hängen. Eine Express-Anwendung kann folgende Arten von Middleware verwenden: @@ -27,14 +32,15 @@ Eine Express-Anwendung kann folgende Arten von Middleware verwenden: - [Integrierte Middleware](#middleware.built-in) - [Middleware von Drittanbietern](#middleware.third-party) -Sie können Middleware auf Anwendungsebene und Routerebene mit einem optionalen Mount-Pfad laden. -Sie können auch eine Reihe von Middleware-Funktionen zusammen laden, die einen Sub-Stack des Middleware-Systems an einem Mount-Punkt erzeugen. +Sie können Middleware auf Anwendungsebene und Routerebene mit einem optionalen Mount-Pfad laden. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Middleware auf Anwendungsebene -Binde Middleware auf Anwendungsebene an eine Instanz des [app object](/api#app) durch Verwendung der `app.use()` und `app. ETHOD()` Funktionen, wobei `METHOD` die HTTP-Methode der Anfrage ist, die die Middleware-Funktion in Kleinbuchstaben behandelt (wie GET, PUT, oder POST) +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -Dieses Beispiel zeigt eine Middleware-Funktion ohne Mount-Pfad. Die Funktion wird jedes Mal ausgeführt, wenn die App eine Anfrage erhält. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -Dieses Beispiel zeigt eine Middleware-Funktion, die auf dem `/user/:id` Pfad eingehängt ist. Die Funktion wird für jede Art von -HTTP-Anfrage im `/user/:id` Pfad ausgeführt. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Routenhandler + Dieses Beispiel zeigt eine Route und deren Handler-Funktion (Middleware-System). Die Funktion bearbeitet GET-Anfragen an den Pfad `/user/:id`. ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Hier ist ein Beispiel für das Laden einer Reihe von Middleware-Funktionen an einem Mount-Punkt, mit einem Mount-Pfad. -Es illustriert einen Middleware-Unterstapel, der Anfrageinformationen für jede Art von HTTP-Anfrage in den Pfad `/user/:id` ausgibt. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Routenhandler ermöglichen es Ihnen, mehrere Routen für einen Pfad zu definieren. Das folgende Beispiel definiert zwei Routen für GET-Anfragen zum Pfad `/user/:id`. Die zweite Route wird keine Probleme verursachen, aber sie wird nie aufgerufen, weil die erste Route den Request-Antwort-Zyklus beendet. +### Multiple route handlers -Dieses Beispiel zeigt einen Middleware-Sub-Stack an, der GET-Anfragen im `/user/:id`-Pfad behandelt. +Routenhandler ermöglichen es Ihnen, mehrere Routen für einen Pfad zu definieren. Das folgende Beispiel definiert zwei Routen für GET-Anfragen zum Pfad `/user/:id`. Die zweite Route wird keine Probleme verursachen, aber sie wird nie aufgerufen, weil die erste Route den Request-Antwort-Zyklus beendet. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -Um die restlichen Middleware-Funktionen eines Routers Middleware-Stacks zu überspringen, rufen Sie `next('route')` auf, um die Kontrolle an die nächste Route zu übergeben. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ Um die restlichen Middleware-Funktionen eines Routers Middleware-Stacks zu über -Dieses Beispiel zeigt einen Middleware-Sub-Stack an, der GET-Anfragen im `/user/:id`-Pfad behandelt. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Middleware kann auch in einem Array für Wiederverwendbarkeit deklariert werden. +### Reusable middleware arrays -Dieses Beispiel zeigt ein Array mit einem Middleware-Sub-Stack an, das GET-Anfragen im Pfad `/user/:id` behandelt +Middleware functions can also be grouped into arrays for better reusability. Dieses Beispiel zeigt ein Array mit einem Middleware-Sub-Stack an, das GET-Anfragen im Pfad `/user/:id` behandelt ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,19 +280,25 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Middleware auf Routerebene -Middleware auf Router-Ebene funktioniert wie Middleware auf Anwendungsebene, es sei denn, es ist an eine Instanz von `express.Router()` gebunden. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); ``` +```ts +import express from 'express'; + +const router = express.Router(); +``` + Laden Sie die Middleware router-level mittels der Funktionen `router.use()` und `router.METHOD()`. Der folgende Beispielcode repliziert das oben angezeigte Middleware-System für Middleware auf Anwendungsebene: @@ -313,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -363,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -413,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -434,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -To skip the rest of the router's middleware functions, call `next('router')` -to pass control back out of the router instance. +### Skipping out of a router -Dieses Beispiel zeigt einen Middleware-Sub-Stack an, der GET-Anfragen im `/user/:id`-Pfad behandelt. +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. + +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -506,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Fehler beim Umgang mit Middleware - - -Bei der Fehlerbehebung der Middleware werden immer _vier_ Argumente verwendet. Sie müssen vier Argumente angeben, um -als Middleware-Funktion zu identifizieren. Selbst wenn du das `next` -Objekt nicht verwenden musst, musst du es angeben, um die Signatur zu pflegen. Andernfalls wird das `next` Objekt -als reguläre Middleware interpretiert und wird Fehler nicht bearbeiten. - - - Definieren Sie die Middleware-Funktionen wie andere Middleware-Funktionen außer mit vier Argumenten anstelle von drei, speziell mit der Signatur `(err, req, res, next)`: ```js @@ -533,7 +543,20 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Details über die Fehlerbehandlungsmittelsoftware finden Sie hier: [Fehlerbehandlung](/guide/error-handling). + + +Bei der Fehlerbehebung der Middleware werden immer _vier_ Argumente verwendet. Sie müssen vier Argumente angeben, um +als Middleware-Funktion zu identifizieren. Selbst wenn du das `next` +Objekt nicht verwenden musst, musst du es angeben, um die Signatur zu pflegen. Andernfalls wird das `next` Objekt +als reguläre Middleware interpretiert und wird Fehler nicht bearbeiten. + + + + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Integrierte Middleware @@ -544,6 +567,8 @@ Express hat die folgenden integrierten Middleware-Funktionen: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. - [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **HINWEIS: Verfügbar mit Express 4.16.0+** +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. **NOTE: Available with Express 4.17.0+** +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. **NOTE: Available with Express 4.17.0+** - [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **HINWEIS: Verfügbar mit Express 4.16.0+** ## Drittanbieter-Middleware @@ -585,4 +610,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Für eine partielle Liste der Middleware-Funktionen von Drittanbietern, die häufig mit Express verwendet werden, siehe: [Middleware](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/de/4x/guide/using-template-engines.mdx b/src/content/docs/de/4x/guide/using-template-engines.mdx index f83a6aa254..f5ae0e68fb 100644 --- a/src/content/docs/de/4x/guide/using-template-engines.mdx +++ b/src/content/docs/de/4x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Template-Engines mit Express verwenden -description: Entdecken Sie, wie Sie Template-Engines wie Pug, Handlebars und EJS mit Express.js integrieren und nutzen können, um dynamische HTML-Seiten effizient zu machen. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ Eine _template engine_ ermöglicht es Ihnen, statische Template-Dateien in Ihrer Variablen in einer Template-Datei mit aktuellen Werten und verwandelt die Vorlage in eine HTML-Datei, die an den Client gesendet wird. Dieser Ansatz erleichtert die Gestaltung einer HTML-Seite. -Der [Express-Anwendungsgenerator](/starter/generator) verwendet [Pug](https://pugjs.org/api/getting-started.html) als Standardwert, aber es unterstützt auch [Handlebars](https://www.npmjs.com/package/handlebars), und [EJS](https://www.npmjs.com/package/ejs), unter anderem. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, das Verzeichnis, in dem sich die Template-Dateien befinden. Eg: `app.set('views', './views')`. Dies ist standardmäßig im Verzeichnis `views` im Root-Verzeichnis der Anwendung. - `view engine`, die zu verwendende Template-Engine. Um zum Beispiel die Mückenvorlagen-Engine zu verwenden: `app.set('view engine', 'pug')`. -Installieren Sie dann das entsprechende Template Engine npm Paket; zum Beispiel um Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ welche `res.render()` aufruft, um den Template-Code zu rendern. Einige Template-Engines folgen nicht dieser Konvention. Die [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) Bibliothek folgt dieser Konvention, indem sie alle populären Template-Engines von Node.js abbildet, und arbeitet daher nahtlos in Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/de/4x/guide/writing-middleware.mdx b/src/content/docs/de/4x/guide/writing-middleware.mdx index 434c037861..6a51a76ff7 100644 --- a/src/content/docs/de/4x/guide/writing-middleware.mdx +++ b/src/content/docs/de/4x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Erfahren Sie, wie Sie benutzerdefinierte Middleware-Funktionen für --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Middleware_ Funktionen sind Funktionen, die Zugriff auf das [request object](/api#req) (`req`), die [Antwort-Objekt](/api#res) (`res`) und die `next` Funktion im Request-Antwort-Zyklus der Anwendung. Die `next`-Funktion ist eine Funktion im Express-Router, der beim Aufruf die Middleware ausführt, die die aktuelle Middleware abfolgt. @@ -199,8 +200,8 @@ Die Middleware-Funktion `myLogger` druckt einfach eine Nachricht, übergibt dann ### Middleware-Funktionsanfragezeit -Als nächstes erstellen wir eine Middleware-Funktion namens "requestTime" und fügen eine Eigenschaft namens `requestTime` -dem Anfrageobjekt hinzu. +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -420,9 +421,13 @@ Anfrage als Fehler und überspringt alle verbleibenden Funktionen zur Fehlerbeha -Weil Sie Zugriff auf das Anfrageobjekt, das Antwortobjekt, die nächste Middleware-Funktion im Stapel und den gesamten Knoten haben. s API, die Möglichkeiten mit Middleware-Funktionen sind endlos. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Für weitere Informationen über Express Middleware siehe: [Express Middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Konfigurierbare Middleware diff --git a/src/content/docs/de/4x/starter/basic-routing.mdx b/src/content/docs/de/4x/starter/basic-routing.mdx index 7587aeb54f..a3f1a27f5b 100644 --- a/src/content/docs/de/4x/starter/basic-routing.mdx +++ b/src/content/docs/de/4x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Lernen Sie die Grundlagen des Routings in Express.js Anwendungen ke --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ bezieht sich darauf, wie eine Anwendung auf einen bestimmten Endpunkt antwortet , die eine URI (oder Pfad) und eine bestimmte HTTP-Request-Methode (GET, POST usw.) ist. @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -Weitere Details zum Routen finden Sie im [Routing Guide](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/de/4x/starter/faq.mdx b/src/content/docs/de/4x/starter/faq.mdx index 12cd1c22ad..05e8e77be5 100644 --- a/src/content/docs/de/4x/starter/faq.mdx +++ b/src/content/docs/de/4x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Finden Sie Antworten auf häufig gestellte Fragen zu Express.js, darunter Themen wie Anwendungsstruktur, Modelle, Authentifizierung, Template-Engines, Fehlerbehandlung und mehr. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## Wie kann ich meine Anwendung strukturieren? Auf diese Frage gibt es keine endgültige Antwort. Die Antwort hängt von @@ -42,7 +44,11 @@ Um die Schnittstellen der Template-Engine und das Caching zu normalisieren, lese [consolidate.js](https://github.com/visionmedia/consolidate.js) Projekt für Unterstützung. Nicht aufgelistete Template-Engines könnten die Express-Signatur trotzdem unterstützen. -Weitere Informationen finden Sie unter [Template-Engines mit Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## Wie gehe ich mit 404 Antworten um? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Weitere Informationen finden Sie unter [Fehlerbehandlung](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Wie kann ich plain HTML rendern? diff --git a/src/content/docs/de/4x/starter/installing.mdx b/src/content/docs/de/4x/starter/installing.mdx index c80351cfdb..aedab5ccf8 100644 --- a/src/content/docs/de/4x/starter/installing.mdx +++ b/src/content/docs/de/4x/starter/installing.mdx @@ -79,7 +79,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/de/4x/starter/static-files.mdx b/src/content/docs/de/4x/starter/static-files.mdx index abb2ac3d09..48ce27ccba 100644 --- a/src/content/docs/de/4x/starter/static-files.mdx +++ b/src/content/docs/de/4x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Verstehen Sie, wie Sie statische Dateien wie Bilder, CSS und JavaSc --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Um statische Dateien wie Bilder, CSS-Dateien und JavaScript-Dateien bereitzustellen, verwenden Sie die in Express integrierte Middleware-Funktion `express.static`. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + Weitere Informationen über die `serve-static` Funktion und ihre Optionen finden Sie unter [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/de/5x/guide/debugging.mdx b/src/content/docs/de/5x/guide/debugging.mdx index ee9bf34278..270f914572 100644 --- a/src/content/docs/de/5x/guide/debugging.mdx +++ b/src/content/docs/de/5x/guide/debugging.mdx @@ -4,104 +4,218 @@ description: Erfahren Sie, wie Sie Debugging-Logs in Express.js-Anwendungen akti --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -Um alle internen Logs zu sehen, die in Express verwendet werden, setzen Sie die Umgebungsvariable `DEBUG` auf -`express:*` beim Starten Ihrer App. +To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*,router,router:*` when launching your app. Routing is handled by the separate [router](https://github.com/pillarjs/router) package, so its logs live under the `router` namespace and are not included in `express:*`. ```bash -$ DEBUG=express:* node index.js +$ DEBUG=express:*,router,router:* node index.js ``` Verwenden Sie unter Windows den entsprechenden Befehl. ```bash -> $env:DEBUG = "express:*"; node index.js +> $env:DEBUG = "express:*,router,router:*"; node index.js ``` -Das Ausführen dieses Befehls auf der vom [Express-Generator] generierten Standard-App (/en/starter/generator) gibt folgende Ausgabe aus: +Running this command on a small app with a JSON body parser and a mounted router prints the following output: + +```cjs title="index.cjs" +const express = require('express'); + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` + +```mjs title="index.mjs" +import express from 'express'; + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` ```bash -$ DEBUG=express:* node ./bin/www - express:router:route new / +0ms - express:router:layer new / +1ms - express:router:route get / +1ms - express:router:layer new / +0ms - express:router:route new / +1ms - express:router:layer new / +0ms - express:router:route get / +0ms - express:router:layer new / +0ms - express:application compile etag weak +1ms - express:application compile query parser extended +0ms - express:application compile trust proxy false +0ms - express:application booting in development mode +1ms - express:router use / query +0ms - express:router:layer new / +0ms - express:router use / expressInit +0ms - express:router:layer new / +0ms - express:router use / favicon +1ms - express:router:layer new / +0ms - express:router use / logger +0ms - express:router:layer new / +0ms - express:router use / jsonParser +0ms - express:router:layer new / +1ms - express:router use / urlencodedParser +0ms - express:router:layer new / +0ms - express:router use / cookieParser +0ms - express:router:layer new / +0ms - express:router use / stylus +90ms - express:router:layer new / +0ms - express:router use / serveStatic +0ms - express:router:layer new / +0ms - express:router use / router +0ms - express:router:layer new / +1ms - express:router use /users router +0ms - express:router:layer new /users +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms +$ DEBUG=express:*,router,router:* node index.js + express:application set "x-powered-by" to true +0ms + express:application set "etag" to 'weak' +3ms + express:application set "etag fn" to [Function: generateETag] +0ms + express:application set "env" to 'development' +1ms + express:application set "query parser" to 'simple' +0ms + express:application set "query parser fn" to [Function: parse] +0ms + express:application set "subdomain offset" to 2 +1ms + express:application set "trust proxy" to false +0ms + express:application set "trust proxy fn" to [Function: trustNone] +1ms + express:application booting in development mode +0ms + express:application set "view" to [Function: View] +0ms + express:application set "views" to '/projects/example/views' +1ms + express:application set "jsonp callback name" to 'callback' +0ms + router use '/' jsonParser +0ms + router:layer new '/' +0ms + router:route new '/' +0ms + router:layer new '/' +3ms + router:route get / +0ms + router:layer new '/' +1ms + router use '/users' router +4ms + router:layer new '/users' +0ms + router:route new '/' +1ms + router:layer new '/' +0ms + router:route get / +1ms + router:layer new '/' +1ms ``` Wenn eine Anfrage an die App gestellt wird, sehen Sie die im Express-Code angegebenen Protokolle: ```bash - express:router dispatching GET / +4h - express:router query : / +2ms - express:router expressInit : / +0ms - express:router favicon : / +0ms - express:router logger : / +1ms - express:router jsonParser : / +0ms - express:router urlencodedParser : / +1ms - express:router cookieParser : / +0ms - express:router stylus : / +0ms - express:router serveStatic : / +2ms - express:router router : / +2ms - express:router dispatching GET / +1ms - express:view lookup "index.pug" +338ms - express:view stat "/projects/example/views/index.pug" +0ms - express:view render "/projects/example/views/index.pug" +1ms + router dispatching GET /users +712ms + router jsonParser : /users +1ms + router trim prefix (/users) from url /users +2ms + router router /users : /users +0ms + router dispatching GET / +0ms +``` + +To see the logs only from the router implementation, set the value of `DEBUG` to `router,router:*`. Um Protokolle nur von der Anwendungsimplementierung zu sehen, setzten Sie den Wert von `DEBUG` auf `express:application`, und so weiter. + +## Using `debug` in your own code + +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: + + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); ``` -Um die Protokolle nur von der Router-Implementierung zu sehen, setzen Sie den Wert `DEBUG` auf `express:router`. Um Protokolle nur von der Anwendungsimplementierung zu sehen, setzten Sie den Wert von `DEBUG` auf `express:application`, und so weiter. +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; -## Anwendungen generiert von `Express` +const debug = debugModule('myapp:server'); +const app = express(); -Eine Anwendung, die durch den Befehl `express generiert` erzeugt wird, benutzt das Modul `debug` und sein Debug-Namensraum wird auf den Namen der Anwendung übertragen. +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); -Wenn Sie zum Beispiel die App mit `$ express Beispiel-App` erstellt haben, können Sie die Debug-Anweisungen mit folgendem Befehl aktivieren: +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` Sie können mehr als einen Debug-Namensraum angeben, indem Sie eine kommaseparierte Namensliste zuweisen: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,router node index.js ``` +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*,router,router:*" } +} +``` + +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Erweiterte Optionen Wenn Sie über Node.js laufen, können Sie ein paar Umgebungsvariablen festlegen, die das Verhalten der Debug-Protokollierung ändern: diff --git a/src/content/docs/de/5x/guide/error-handling.mdx b/src/content/docs/de/5x/guide/error-handling.mdx index 3c4cf64f18..7701c70a9c 100644 --- a/src/content/docs/de/5x/guide/error-handling.mdx +++ b/src/content/docs/de/5x/guide/error-handling.mdx @@ -14,6 +14,8 @@ sowohl synchron als auch asynchron auftritt. Express kommt mit einem Standardfeh Es ist wichtig sicherzustellen, dass Express alle Fehler, die auftreten, während Routen-Handler und Middleware ausführt. +### Errors in synchronous code + Fehler, die im synchronen Code innerhalb von Routenhandlern und Middleware auftreten, erfordern keine zusätzliche Arbeit. If synchronous code throws an error, then Express will catch and process it. Zum Beispiel: @@ -32,51 +34,24 @@ app.get('/', (req: Request, res: Response) => { }); ``` -For errors returned from asynchronous functions invoked by route handlers -and middleware, you must pass them to the `next()` function, where Express will -catch and process them. Zum Beispiel: - -```js -app.get('/', (req, res, next) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` +### Errors in asynchronous code -```ts -import { type Request, type Response, type NextFunction } from 'express'; - -app.get('/', (req: Request, res: Response, next: NextFunction) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` - -Starting with Express 5, route handlers and middleware that return a Promise -will call `next(value)` automatically when they reject or throw an error. -Zum Beispiel: +The recommended way to write asynchronous handlers is with `async` functions. +Route handlers and middleware that return a Promise call `next(value)` +automatically when they reject or throw an error, and `async` functions always +return a Promise, so their errors reach Express with no extra work. Zum Beispiel: ```js -app.get('/user/:id', async (req, res, next) => { +app.get('/user/:id', async (req, res) => { const user = await getUserById(req.params.id); res.send(user); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', async (req: Request, res: Response) => { const user = await getUserById(req.params.id); res.send(user); }); @@ -90,49 +65,41 @@ Wenn du etwas an die `next()` Funktion übergibt (außer den String `'route'`), Express betrachtet die aktuelle Anfrage als Fehler und überspringt alle verbleibenden Funktionen zur Fehlerbehandlung und Middleware. -Wenn der Rückruf in einer Sequenz keine Daten enthält, nur Fehler, kannst du den Code -wie folgt vereinfachen: +### Working with promise chains + +If you build a promise chain instead of using an `async` function, return the +promise from the handler and Express will likewise call `next` automatically +when it rejects: ```js -app.get('/', [ - function (req, res, next) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req, res) { - res.send('OK'); - }, -]); +app.get('/', (req, res) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/', [ - function (req: Request, res: Response, next: NextFunction) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req: Request, res: Response) { - res.send('OK'); - }, -]); +app.get('/', (req: Request, res: Response) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` -Im obigen Beispiel wird `next` als Callback für `fs.writeFile` bereitgestellt, -, das mit oder ohne Fehler aufgerufen wird. Wenn kein Fehler vorliegt, wird der zweite --Handler ausgeführt, sonst fängt und verarbeitet Express den Fehler. - -Sie müssen Fehler, die im asynchronen Code auftreten, der von Routenhandlern oder -Middleware aufgerufen wird, auffangen und an Express zur Verarbeitung weiterleiten. Zum Beispiel: +If the promise is not returned, Express does not know it exists, and you must +route the error yourself by providing `next` as the final catch handler. +Without it, the rejection would be unhandled and crash the process: ```js app.get('/', (req, res, next) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` @@ -140,31 +107,32 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` -Das obige Beispiel benutzt einen "try...catch"-Baustein, um Fehler im -asynchronen Code zu fangen und sie an den Express zu übergeben. Wenn der Block `try...catch` -weggelassen wurde, würde Express den Fehler nicht auffinden, da er nicht Teil des synchronen -Handlercodes ist. +This works because if a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, `.catch` calls its handler with the error as the first argument, which is exactly the argument `next` expects, so the error reaches Express. -Verwende Versprechungen, um den Overhead des `try...catch`-Bausteins zu vermeiden oder wenn du Funktionen -benutzt, die Versprechen zurückgeben. Zum Beispiel: +### Working with callback APIs + +Errors produced by callback-based APIs, such as those in `node:fs`, are not +thrown and are not part of any promise. The callback receives them as its first +argument, and you must pass them to the `next()` function yourself, where +Express will catch and process them. Zum Beispiel: ```js app.get('/', (req, res, next) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` @@ -172,17 +140,46 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` -Da Versprechungen automatisch sowohl synchrone Fehler als auch abgelehnte Versprechungen fangen, -du kannst einfach `next` angeben, da der letzte Catch Handler und Express Fehler fängt an -weil der Catch-Handler den Fehler als erstes Argument angibt. +Wenn der Rückruf in einer Sequenz keine Daten enthält, nur Fehler, kannst du den Code +wie folgt vereinfachen: + +```js +app.get('/', [ + function (req, res, next) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req, res) { + res.send('OK'); + }, +]); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', [ + function (req: Request, res: Response, next: NextFunction) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req: Request, res: Response) { + res.send('OK'); + }, +]); +``` + +Im obigen Beispiel wird `next` als Callback für `fs.writeFile` bereitgestellt, +, das mit oder ohne Fehler aufgerufen wird. Wenn kein Fehler vorliegt, wird der zweite +-Handler ausgeführt, sonst fängt und verarbeitet Express den Fehler. Sie können auch eine Kette von Handlern verwenden, um sich auf synchrone Fehler zu stützen, indem Sie den asynchronen Code auf etwas Triviales reduzieren. Zum Beispiel: @@ -219,14 +216,49 @@ app.get('/', [ ]); ``` -Das obige Beispiel hat ein paar triviale Anweisungen aus dem Aufruf `readFile` -. If `readFile` causes an error, then it passes the error to Express, otherwise you +The above example contains a couple of trivial statements following the `readFile` +call. If `readFile` causes an error, then it passes the error to Express, otherwise you quickly return to the world of synchronous error handling in the next handler in the chain. Dann versucht das obige Beispiel die Daten zu verarbeiten. Wenn dies fehlschlägt, fängt der Synchron-Fehlerhandler ihn ab. Hätten Sie diese Verarbeitung innerhalb von mit dem `readFile` Callback durchgeführt, dann könnte sich die Anwendung beenden und die Express-Fehler Handler würden nicht laufen. +Finally, for asynchronous code that provides no error-first callback, such as a +timer, catch errors inside the asynchronous code itself and pass them to +Express: + +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', (req: Request, res: Response, next: NextFunction) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +Das obige Beispiel benutzt einen "try...catch"-Baustein, um Fehler im +asynchronen Code zu fangen und sie an den Express zu übergeben. Wenn der Block `try...catch` +weggelassen wurde, würde Express den Fehler nicht auffinden, da er nicht Teil des synchronen +Handlercodes ist. + Welche Methode Sie auch immer verwenden, wenn Sie wollen, dass Express-Fehlerbehandler aufgerufen werden und die -Anwendung überleben soll, Sie müssen sicherstellen, dass Express den Fehler empfängt. @@ -424,7 +456,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Auch in diesem Beispiel wird `clientErrorHandler` wie folgt definiert; in diesem Fall wird der Fehler explizit an den nächsten weitergegeben. -Beachten Sie, dass, wenn _not_ in einer Fehlerbehandlungsfunktion "Weiter" aufruft, Sie dafür verantwortlich sind, die Antwort zu schreiben (und zu beenden). Andernfalls werden diese Anträge "hängen" und sind nicht für die Müllsammlung berechtigt. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Andernfalls werden diese Anträge "hängen" und sind nicht für die Müllsammlung berechtigt. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/de/5x/guide/overriding-express-api.mdx b/src/content/docs/de/5x/guide/overriding-express-api.mdx index eddfc6a403..a3afb12be3 100644 --- a/src/content/docs/de/5x/guide/overriding-express-api.mdx +++ b/src/content/docs/de/5x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -Die Express API besteht aus verschiedenen Methoden und Eigenschaften auf den Anfrage- und Antwort-Objekten. Diese werden vom Prototyp geerbt. Es gibt zwei Erweiterungspunkte für die Express API: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. Diese werden vom Prototyp geerbt. Es gibt zwei Erweiterungspunkte für die Express API: 1. Die globalen Prototypen unter `express.request` und `express.response`. 2. App-spezifische Prototypen bei `app.request` und `app.response`. diff --git a/src/content/docs/de/5x/guide/routing.mdx b/src/content/docs/de/5x/guide/routing.mdx index 4115aa0a0d..e7fd83866b 100644 --- a/src/content/docs/de/5x/guide/routing.mdx +++ b/src/content/docs/de/5x/guide/routing.mdx @@ -9,11 +9,11 @@ _Routing_ bezieht sich darauf, wie die Endpunkte einer Anwendung (URIs) auf Kund Für eine Einführung in das Routing siehe [Basic routing](/starter/basic-routing). Du definierst Routing, indem du Methoden des Express `app` Objekts verwendest, die den HTTP-Methoden entsprechen; -zum Beispiel, `app. et()` um GET-Anfragen und `app.post` zu behandeln, um POST-Anfragen zu bearbeiten. For a full list, +zum Beispiel, `app.get()` um GET-Anfragen und `app.post` zu behandeln, um POST-Anfragen zu bearbeiten. For a full list, see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. Mit anderen Worten, die Anwendung "lauscht" für Anforderungen, die mit der angegebenen Route(s) und Methode(n) übereinstimmen und wenn es ein Spiel erkennt, ruft es die angegebene Callback-Funktion auf. +Mit anderen Worten, die Anwendung "lauscht" für Anforderungen, die mit der angegebenen Route(s) und Methode(n) übereinstimmen und wenn es ein Spiel erkennt, ruft es die angegebene Callback-Funktion auf. Mit anderen Worten, die Anwendung "lauscht" für Anforderungen, die mit der angegebenen Route(s) und Methode(n) übereinstimmen und wenn es ein Spiel erkennt, ruft es die angegebene Callback-Funktion auf. In der Tat können die Routing-Methoden mehr als eine Callback-Funktion als Argumente haben. Mit mehreren Callback-Funktionen, es ist wichtig, `next` als Argument für die Callback-Funktion zur Verfügung zu stellen und dann `next()` im Körper der Funktion aufzurufen, um die Steuerung @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express unterstützt Methoden, die allen HTTP-Anfragemethoden entsprechen: `get`, `post` und so weiter. For a full list, see [app.METHOD](/api/application#appmethod). -Es gibt eine spezielle Routing-Methode, `app.all()`, die benutzt wird, um Middleware-Funktionen an einem Pfad für _all_ HTTP-Requestmethoden zu laden. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +Es gibt eine spezielle Routing-Methode, `app.all()`, die benutzt wird, um Middleware-Funktionen an einem Pfad für _all_ HTTP-Requestmethoden zu laden. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Routenpfade -Routenpfade in Kombination mit einer Anfragemethode definieren die Endpunkte, an denen Anfragen gestellt werden können. Routenpfade können Strings oder reguläre Ausdrücke sein. +Routenpfade in Kombination mit einer Anfragemethode definieren die Endpunkte, an denen Anfragen gestellt werden können. Routenpfade können Strings oder reguläre Ausdrücke sein. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -153,77 +153,9 @@ app.get('/random.text', (req: Request, res: Response) => { }); ``` -### Wildcards - -Platzhalter entsprechen jedem Pfad nach einem Präfix. Sie müssen einen Namen haben, genau wie Routenparameter, und werden als Arrays von Pfadsegmenten erfasst. - -```js -app.get('/files/*filepath', (req, res) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -Um auch dem Wurzelpfad zu entsprechen, wickeln Sie den Platzhalter in Klammern: - -```js -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req, res) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req: Request, res: Response) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -### Optionale Segmente - -Verwenden Sie Klammern um optionale Segmente in einem Routenpfad zu definieren. Wenn das Segment nicht vorhanden ist, wird der Parameter von `req.params` weggelassen. - -```js -app.get('/:file{.:ext}', (req, res) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/:file{.:ext}', (req: Request, res: Response) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -Die Zeichen `?`, `+`, `*`, `[]` und `()` sind reserviert und können nicht als buchstäbliche Zeichen in Routenpfaden verwendet werden. Benutze `\`, um sie bei Bedarf zu maskieren. +The characters `?`, `+`, `*`, `[]`, `()`, and `!` are reserved and cannot be used as literal characters in route paths, and braces are reserved for [optional segments](#optional-segments). Benutze `\`, um sie bei Bedarf zu maskieren. @@ -259,7 +191,11 @@ app.get(/.*fly$/, (req: Request, res: Response) => { ## Routenparameter -Routenparameter sind URL-Segmente, die zur Erfassung der an ihrer Position in der URL angegebenen Werte verwendet werden. Die erfassten Werte werden im Objekt `req.params` gefüllt, wobei der Name des im Pfad angegebenen Routenparameter als ihre jeweiligen Schlüssel angegeben ist. +Routenparameter sind URL-Segmente, die zur Erfassung der an ihrer Position in der URL angegebenen Werte verwendet werden. Die erfassten Werte werden im Objekt `req.params` gefüllt, wobei der Name des im Pfad angegebenen Routenparameter als ihre jeweiligen Schlüssel angegeben ist. They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces. + +### Named parameters + +Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below. ``` Route path: /users/:userId/books/:bookId @@ -293,7 +229,7 @@ app.get('/users/:userId/books/:bookId', sendParams); -Der Name der Routenparameter muss aus "Wortzeichen" ([A-Za-z0-9_] ) bestehen. +The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example `:"user-name"`. @@ -313,14 +249,122 @@ req.params: { "genus": "Prunus", "species": "persica" } -Regexp Zeichen werden in Routenpfaden nicht unterstützt. Verwenden Sie stattdessen ein Array von Pfaden oder regulären Ausdrücken. -Weitere Informationen finden Sie in der Syntax [Pfadroute Match](/en/guide/migrating-5#path-syntax) . +Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as `:userId(\d+)`. Use an array of paths or a full regular expression instead. +Weitere Informationen finden Sie in der Syntax [Pfadroute Match](/guide/migrating-5#path-route-matching-syntax). +### Wildcards + +Platzhalter entsprechen jedem Pfad nach einem Präfix. Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string. + +```js +app.get('/files/*filepath', (req, res) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +Um auch dem Wurzelpfad zu entsprechen, wickeln Sie den Platzhalter in Klammern: + +```js +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req, res) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req: Request, res: Response) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +### Optionale Segmente + +Verwenden Sie Klammern um optionale Segmente in einem Routenpfad zu definieren. Wenn das Segment nicht vorhanden ist, wird der Parameter von `req.params` weggelassen. + +```js +app.get('/:file{.:ext}', (req, res) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/:file{.:ext}', (req: Request, res: Response) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters: + +```js +app.get('/user/\{:id}', (req, res) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req, res) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/user/\{:id}', (req: Request, res: Response) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req: Request, res: Response) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +Verwechsle die Position des Schrägstrichs im Routenpfad nicht mit der [`strict routing`-Einstellung](/api/application/#application-settings), die sich auf die Anfrage-URL bezieht: Sie steuert, ob eine URL, die mit einem Schrägstrich endet, den der Routenpfad nicht verlangt, trotzdem übereinstimmt. Zum Beispiel stimmt eine Anfrage an `/order/` standardmäßig mit der Route `/order{/:id}` überein, gibt aber einen 404-Fehler zurück, wenn strict routing aktiviert ist; der abschließende Schrägstrich von `/user/` ist davon nicht betroffen, weil die Route `/user/\{:id}` ihn verlangt. Alle in den obigen Beispielen kommentierten Anfragen verhalten sich unabhängig von dieser Einstellung gleich.## Route handlersYou can provide multiple callback functions that + ## Routenhandler -Du kannst mehrere Callback-Funktionen bereitstellen, die sich wie [middleware](/guide/using-middleware) verhalten um eine Anfrage zu bearbeiten. Die einzige Ausnahme ist, dass diese Callbacks `next('route')` aufrufen könnten, um die restlichen Rufnummern zu umgehen. Sie können diesen Mechanismus nutzen, um Vorbedingungen auf einer Route aufzuerlegen, dann die Kontrolle an die nachfolgenden Routen übergeben, wenn es keinen Grund gibt, mit der aktuellen Route fortzufahren. +Du kannst mehrere Callback-Funktionen bereitstellen, die sich wie [middleware](/guide/using-middleware) verhalten um eine Anfrage zu bearbeiten. Die einzige Ausnahme ist, dass diese Callbacks `next('route')` aufrufen könnten, um die restlichen Rufnummern zu umgehen. Sie können diesen Mechanismus nutzen, um Vorbedingungen auf einer Route aufzuerlegen, dann die Kontrolle an die nachfolgenden Routen übergeben, wenn es keinen Grund gibt, mit der aktuellen Route fortzufahren.```js +app.get('/user/:id', (req, res, next) => { +if (req.params.i + +```` ```js app.get('/user/:id', (req, res, next) => { @@ -333,7 +377,7 @@ app.get('/user/:id', (req, res, next) => { app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0'); }); -``` +```` ```ts import { type Request, type Response, type NextFunction } from 'express'; @@ -355,15 +399,17 @@ In diesem Beispiel: - `GET /user/5` → behandelt durch die erste Route → sendet "Benutzer 5" - `GET /user/0` → erste Routenaufrufe `next('route')`, überspringt zur nächsten passenden `/user/:id` Route -Routenhandler können in Form einer Funktion, eines Arrays von Funktionen oder Kombinationen beider sein, wie in den folgenden Beispielen gezeigt. +Routenhandler können in Form einer Funktion, eines Arrays von Funktionen oder Kombinationen beider sein, wie in den folgenden Beispielen gezeigt.A single callback function can handle a route. For example:```js + +```` -Eine einzelne Callback-Funktion kann eine Route handhaben. Zum Beispiel: +Mehr als eine Callback-Funktion kann eine Route handhaben (stelle sicher, dass du das `next` Objekt angibst). ```js app.get('/example/a', (req, res) => { res.send('Hello from A!'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -373,7 +419,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -Mehr als eine Callback-Funktion kann eine Route handhaben (stelle sicher, dass du das `next` Objekt angibst). Zum Beispiel: +Eine Kombination aus unabhängigen Funktionen und Arrays von Funktionen kann eine Route handhaben. Zum Beispiel: ```js app.get( @@ -403,7 +449,7 @@ app.get( ); ``` -Ein Array von Callback-Funktionen kann eine Route handhaben. Zum Beispiel: +Ein Array von Callback-Funktionen kann eine Route handhaben. ```js const cb0 = function (req, res, next) { @@ -497,26 +543,32 @@ app.get( ## Antwortmethoden -Die Methoden auf dem Antwortobjekt (`res`) in der folgenden Tabelle können eine Antwort an den Client senden und den Request-Antwort-Zyklus beenden. Wenn keine dieser Methoden von einem Routenhandler aufgerufen wird, bleibt die Client-Anfrage hängen. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. Wenn keine dieser Methoden von einem Routenhandler aufgerufen wird, bleibt die Client-Anfrage hängen.| Method | Description -| Methode | Beschreibung | -| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------- | -| [res.download()](/api/response#resdownload) | Fordern Sie eine Datei zum Download an. | -| [res.end()](/api/response#resend) | Beenden Sie den Antwort-Prozess. | -| [res.json()](/api/response#resjson) | Sende eine JSON-Antwort. | -| [res.jsonp()](/api/response#resjsonp) | Senden Sie eine JSON-Antwort mit JSONP-Unterstützung. | -| [res.redirect()](/api/response#resredirect) | Anfrage umleiten. | -| [res.render()](/api/response#resrender) | Render a view template. | -| [res.send()](/api/response#ressend) | Senden Sie eine Antwort von verschiedenen Typen. | -| [res.sendFile()](/api/response#ressendfile) | Senden Sie eine Datei als octet-Stream. | -| [res.sendStatus()](/api/response#ressendstatus) | Legen Sie den Antwort-Statuscode fest und senden Sie seine Zeichenfolge Repräsentation als Antwortkörper. | +| | | +| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/api/response#resdownload) | Fordern Sie eine Datei zum Download an. | +| [res.end()](/api/response#resend) | Beenden Sie den Antwort-Prozess. | +| [res.json()](/api/response#resjson) | Sende eine JSON-Antwort. | +| [res.jsonp()](/api/response#resjsonp) | Senden Sie eine JSON-Antwort mit JSONP-Unterstützung. | +| | Anfrage umleiten. | +| [res.render()](/api/response#resrender) | Render a view template. | +| [res.send()](/api/response#ressend) | Senden Sie eine Antwort von verschiedenen Typen. | +| [res.sendFile()](/api/response#ressendfile) | Senden Sie eine Datei als octet-Stream. | +| [res.sendStatus()](/api/response#ressendstatus) | Legen Sie den Antwort-Statuscode fest und senden Sie seine Zeichenfolge Repräsentation als Antwortkörper. \|## app.route()You can create chainable route handlers for a rou | ## app.route() Sie können verkettende Routenhandler für einen Routenpfad erstellen, indem Sie `app.route()` verwenden. -Da der Weg an einem einzigen Ort angegeben wird, ist die Schaffung modularer Routen hilfreich, ebenso wie die Reduzierung von Redundanz und Typos. Weitere Informationen über Routen finden Sie unter [Router() documentation](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router).Here is an example of chained route handlers that are defined by us + +Hier ist ein Beispiel für verkettete Routenhandler, die mit `app.route()` definiert werden.```js +app +.route('/book') +.get((req, res) => { +res.send('Ge -Hier ist ein Beispiel für verkettete Routenhandler, die mit `app.route()` definiert werden. +```` ```js app @@ -530,7 +582,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -550,9 +602,9 @@ app ## express.Router -Verwende die Klasse `express.Router`, um modulare mountbare Routenhandler zu erstellen. Eine `Router`-Instanz ist ein komplettes Middleware- und Routing-System; aus diesem Grund wird sie oft als "Mini-App" bezeichnet. +Verwende die Klasse `express.Router`, um modulare mountbare Routenhandler zu erstellen. Eine `Router`-Instanz ist ein komplettes Middleware- und Routing-System; aus diesem Grund wird sie oft als "Mini-App" bezeichnet.The following example creates a router as a module, loads a middlew -Das folgende Beispiel erzeugt einen Router als Modul, lädt eine Middleware-Funktion darin definiert einige Routen und mountet das Router-Modul auf einem Pfad in der Hauptanwendung. +Das folgende Beispiel erzeugt einen Router als Modul, lädt eine Middleware-Funktion darin definiert einige Routen und mountet das Router-Modul auf einem Pfad in der Hauptanwendung.Create a router file named `birds.js` in the app directory, with th Erstelle eine Router-Datei namens `birds.js` im App-Verzeichnis, mit folgendem Inhalt: @@ -645,10 +697,13 @@ import birds from './birds'; app.use('/birds', birds); ``` -Die App wird nun in der Lage sein, Anfragen an `/birds` und `/birds/about` zu bearbeiten, aufrufen sowie die Middleware-Funktion `timeLog` aufrufen, die spezifisch für die Route ist. +Die App wird nun in der Lage sein, Anfragen an `/birds` und `/birds/about` zu bearbeiten, aufrufen sowie die Middleware-Funktion `timeLog` aufrufen, die spezifisch für die Route ist.But if the parent route `/birds` has path parameters, it will not b -Aber wenn die übergeordnete Route `/birds` Pfadparameter hat, wird sie standardmäßig nicht von den Unterrouten aus erreichbar sein. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +Aber wenn die übergeordnete Route `/birds` Pfadparameter hat, wird sie standardmäßig nicht von den Unterrouten aus erreichbar sein. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter).```js +const router = express.Router({ mergeParams: true }); + +```` ```js const router = express.Router({ mergeParams: true }); -``` +```` diff --git a/src/content/docs/de/5x/guide/using-middleware.mdx b/src/content/docs/de/5x/guide/using-middleware.mdx index 41da03d43d..356b391198 100644 --- a/src/content/docs/de/5x/guide/using-middleware.mdx +++ b/src/content/docs/de/5x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Lernen Sie, wie Sie Middleware in Express.js-Anwendungen verwenden, import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express ist ein Routing- und Middleware-Webframework mit minimaler Funktionalität: Eine Express-Anwendung ist im Wesentlichen eine Reihe von Middleware-Funktionsaufrufen. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -_Middleware_ Funktionen sind Funktionen, die Zugriff auf das [request object](/api#req) (`req`), das [Antwort-Objekt](/api#res) (`res`) und die nächste Middleware-Funktion im Request-Antwort-Zyklus der Anwendung. Die nächste Middleware-Funktion wird üblicherweise durch eine Variable namens `next` bezeichnet. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Middleware-Funktionen können folgende Aufgaben ausführen: - Führe jeden Code aus. -- Änderungen an der Anfrage und den Antwort-Objekten vornehmen. +- Modify the request and response objects. - Beende den Request-Antwort-Zyklus. -- Rufen Sie die nächste Middleware-Funktion im Stack auf. +- Pass control to the next middleware function. -Wenn die aktuelle Middleware-Funktion den Request-Antwort-Zyklus nicht beendet, muss sie `next()` aufrufen, um die Kontrolle an die nächste Middleware-Funktion zu übergeben. Andernfalls bleibt die Anfrage hängen. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Andernfalls bleibt die Anfrage hängen. Eine Express-Anwendung kann folgende Arten von Middleware verwenden: @@ -27,14 +32,15 @@ Eine Express-Anwendung kann folgende Arten von Middleware verwenden: - [Integrierte Middleware](#middleware.built-in) - [Middleware von Drittanbietern](#middleware.third-party) -Sie können Middleware auf Anwendungsebene und Routerebene mit einem optionalen Mount-Pfad laden. -Sie können auch eine Reihe von Middleware-Funktionen zusammen laden, die einen Sub-Stack des Middleware-Systems an einem Mount-Punkt erzeugen. +Sie können Middleware auf Anwendungsebene und Routerebene mit einem optionalen Mount-Pfad laden. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Middleware auf Anwendungsebene -Binde Middleware auf Anwendungsebene an eine Instanz des [app object](/api#app) durch Verwendung der `app.use()` und `app. ETHOD()` Funktionen, wobei `METHOD` die HTTP-Methode der Anfrage ist, die die Middleware-Funktion in Kleinbuchstaben behandelt (wie GET, PUT, oder POST) +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -Dieses Beispiel zeigt eine Middleware-Funktion ohne Mount-Pfad. Die Funktion wird jedes Mal ausgeführt, wenn die App eine Anfrage erhält. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -Dieses Beispiel zeigt eine Middleware-Funktion, die auf dem `/user/:id` Pfad eingehängt ist. Die Funktion wird für jede Art von -HTTP-Anfrage im `/user/:id` Pfad ausgeführt. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Routenhandler + Dieses Beispiel zeigt eine Route und deren Handler-Funktion (Middleware-System). Die Funktion bearbeitet GET-Anfragen an den Pfad `/user/:id`. ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Hier ist ein Beispiel für das Laden einer Reihe von Middleware-Funktionen an einem Mount-Punkt, mit einem Mount-Pfad. -Es illustriert einen Middleware-Unterstapel, der Anfrageinformationen für jede Art von HTTP-Anfrage in den Pfad `/user/:id` ausgibt. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Routenhandler ermöglichen es Ihnen, mehrere Routen für einen Pfad zu definieren. Das folgende Beispiel definiert zwei Routen für GET-Anfragen zum Pfad `/user/:id`. Die zweite Route wird keine Probleme verursachen, aber sie wird nie aufgerufen, weil die erste Route den Request-Antwort-Zyklus beendet. +### Multiple route handlers -Dieses Beispiel zeigt einen Middleware-Sub-Stack an, der GET-Anfragen im `/user/:id`-Pfad behandelt. +Routenhandler ermöglichen es Ihnen, mehrere Routen für einen Pfad zu definieren. Das folgende Beispiel definiert zwei Routen für GET-Anfragen zum Pfad `/user/:id`. Die zweite Route wird keine Probleme verursachen, aber sie wird nie aufgerufen, weil die erste Route den Request-Antwort-Zyklus beendet. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -Um die restlichen Middleware-Funktionen eines Routers Middleware-Stacks zu überspringen, rufen Sie `next('route')` auf, um die Kontrolle an die nächste Route zu übergeben. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ Um die restlichen Middleware-Funktionen eines Routers Middleware-Stacks zu über -Dieses Beispiel zeigt einen Middleware-Sub-Stack an, der GET-Anfragen im `/user/:id`-Pfad behandelt. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Middleware kann auch in einem Array für Wiederverwendbarkeit deklariert werden. +### Reusable middleware arrays -Dieses Beispiel zeigt ein Array mit einem Middleware-Sub-Stack an, das GET-Anfragen im Pfad `/user/:id` behandelt +Middleware functions can also be grouped into arrays for better reusability. Dieses Beispiel zeigt ein Array mit einem Middleware-Sub-Stack an, das GET-Anfragen im Pfad `/user/:id` behandelt ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,14 +280,14 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Middleware auf Routerebene -Middleware auf Router-Ebene funktioniert wie Middleware auf Anwendungsebene, es sei denn, es ist an eine Instanz von `express.Router()` gebunden. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); @@ -319,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -369,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -419,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -440,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -To skip the rest of the router's middleware functions, call `next('router')` -to pass control back out of the router instance. +### Skipping out of a router + +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. -Dieses Beispiel zeigt einen Middleware-Sub-Stack an, der GET-Anfragen im `/user/:id`-Pfad behandelt. +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -512,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Fehler beim Umgang mit Middleware - - -Bei der Fehlerbehebung der Middleware werden immer _vier_ Argumente verwendet. Sie müssen vier Argumente angeben, um -als Middleware-Funktion zu identifizieren. Selbst wenn du das `next` -Objekt nicht verwenden musst, musst du es angeben, um die Signatur zu pflegen. Andernfalls wird das `next` Objekt -als reguläre Middleware interpretiert und wird Fehler nicht bearbeiten. - - - Definieren Sie die Middleware-Funktionen wie andere Middleware-Funktionen außer mit vier Argumenten anstelle von drei, speziell mit der Signatur `(err, req, res, next)`: ```js @@ -539,18 +543,30 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Details über die Fehlerbehandlungsmittelsoftware finden Sie hier: [Fehlerbehandlung](/guide/error-handling). + -## Integrierte Middleware +Bei der Fehlerbehebung der Middleware werden immer _vier_ Argumente verwendet. Sie müssen vier Argumente angeben, um +als Middleware-Funktion zu identifizieren. Selbst wenn du das `next` +Objekt nicht verwenden musst, musst du es angeben, um die Signatur zu pflegen. Andernfalls wird das `next` Objekt +als reguläre Middleware interpretiert und wird Fehler nicht bearbeiten. + + + + -Ab Version 4.x ist Express nicht mehr abhängig von [Connect](https://github.com/senchalabs/connect). Die Middleware- --Funktionen, die zuvor mit Express integriert wurden, befinden sich nun in separaten Modulen; siehe [Liste der Middleware-Funktionen](https://github.com/senchalabs/connect#middleware). +For more information, see the [Error handling](/guide/error-handling) guide. + + + +## Integrierte Middleware Express hat die folgenden integrierten Middleware-Funktionen: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. -- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **HINWEIS: Verfügbar mit Express 4.16.0+** -- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **HINWEIS: Verfügbar mit Express 4.16.0+** +- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. +- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. ## Drittanbieter-Middleware @@ -591,4 +607,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Für eine partielle Liste der Middleware-Funktionen von Drittanbietern, die häufig mit Express verwendet werden, siehe: [Middleware](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/de/5x/guide/using-template-engines.mdx b/src/content/docs/de/5x/guide/using-template-engines.mdx index f83a6aa254..f5ae0e68fb 100644 --- a/src/content/docs/de/5x/guide/using-template-engines.mdx +++ b/src/content/docs/de/5x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Template-Engines mit Express verwenden -description: Entdecken Sie, wie Sie Template-Engines wie Pug, Handlebars und EJS mit Express.js integrieren und nutzen können, um dynamische HTML-Seiten effizient zu machen. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ Eine _template engine_ ermöglicht es Ihnen, statische Template-Dateien in Ihrer Variablen in einer Template-Datei mit aktuellen Werten und verwandelt die Vorlage in eine HTML-Datei, die an den Client gesendet wird. Dieser Ansatz erleichtert die Gestaltung einer HTML-Seite. -Der [Express-Anwendungsgenerator](/starter/generator) verwendet [Pug](https://pugjs.org/api/getting-started.html) als Standardwert, aber es unterstützt auch [Handlebars](https://www.npmjs.com/package/handlebars), und [EJS](https://www.npmjs.com/package/ejs), unter anderem. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, das Verzeichnis, in dem sich die Template-Dateien befinden. Eg: `app.set('views', './views')`. Dies ist standardmäßig im Verzeichnis `views` im Root-Verzeichnis der Anwendung. - `view engine`, die zu verwendende Template-Engine. Um zum Beispiel die Mückenvorlagen-Engine zu verwenden: `app.set('view engine', 'pug')`. -Installieren Sie dann das entsprechende Template Engine npm Paket; zum Beispiel um Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ welche `res.render()` aufruft, um den Template-Code zu rendern. Einige Template-Engines folgen nicht dieser Konvention. Die [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) Bibliothek folgt dieser Konvention, indem sie alle populären Template-Engines von Node.js abbildet, und arbeitet daher nahtlos in Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/de/5x/guide/writing-middleware.mdx b/src/content/docs/de/5x/guide/writing-middleware.mdx index 4d3fb548f6..8fca148f91 100644 --- a/src/content/docs/de/5x/guide/writing-middleware.mdx +++ b/src/content/docs/de/5x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Erfahren Sie, wie Sie benutzerdefinierte Middleware-Funktionen für --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Middleware_ Funktionen sind Funktionen, die Zugriff auf das [request object](/api#req) (`req`), die [Antwort-Objekt](/api#res) (`res`) und die `next` Funktion im Request-Antwort-Zyklus der Anwendung. Die `next`-Funktion ist eine Funktion im Express-Router, der beim Aufruf die Middleware ausführt, die die aktuelle Middleware abfolgt. @@ -170,8 +171,8 @@ Die Middleware-Funktion `myLogger` druckt einfach eine Nachricht, übergibt dann ### Middleware-Funktionsanfragezeit -Als nächstes erstellen wir eine Middleware-Funktion namens "requestTime" und fügen eine Eigenschaft namens `requestTime` -dem Anfrageobjekt hinzu. +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -391,9 +392,13 @@ Anfrage als Fehler und überspringt alle verbleibenden Funktionen zur Fehlerbeha -Weil Sie Zugriff auf das Anfrageobjekt, das Antwortobjekt, die nächste Middleware-Funktion im Stapel und den gesamten Knoten haben. s API, die Möglichkeiten mit Middleware-Funktionen sind endlos. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Für weitere Informationen über Express Middleware siehe: [Express Middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Konfigurierbare Middleware diff --git a/src/content/docs/de/5x/starter/basic-routing.mdx b/src/content/docs/de/5x/starter/basic-routing.mdx index 7587aeb54f..a3f1a27f5b 100644 --- a/src/content/docs/de/5x/starter/basic-routing.mdx +++ b/src/content/docs/de/5x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Lernen Sie die Grundlagen des Routings in Express.js Anwendungen ke --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ bezieht sich darauf, wie eine Anwendung auf einen bestimmten Endpunkt antwortet , die eine URI (oder Pfad) und eine bestimmte HTTP-Request-Methode (GET, POST usw.) ist. @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -Weitere Details zum Routen finden Sie im [Routing Guide](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/de/5x/starter/faq.mdx b/src/content/docs/de/5x/starter/faq.mdx index 3f7dc5ae85..ed047dca4e 100644 --- a/src/content/docs/de/5x/starter/faq.mdx +++ b/src/content/docs/de/5x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Finden Sie Antworten auf häufig gestellte Fragen zu Express.js, darunter Themen wie Anwendungsstruktur, Modelle, Authentifizierung, Template-Engines, Fehlerbehandlung und mehr. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## Wie kann ich meine Anwendung strukturieren? Auf diese Frage gibt es keine endgültige Antwort. Die Antwort hängt von @@ -42,7 +44,11 @@ Um die Schnittstellen der Template-Engine und das Caching zu normalisieren, lese [consolidate.js](https://github.com/visionmedia/consolidate.js) Projekt für Unterstützung. Nicht aufgelistete Template-Engines könnten die Express-Signatur trotzdem unterstützen. -Weitere Informationen finden Sie unter [Template-Engines mit Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## Wie gehe ich mit 404 Antworten um? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Weitere Informationen finden Sie unter [Fehlerbehandlung](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Wie kann ich plain HTML rendern? diff --git a/src/content/docs/de/5x/starter/installing.mdx b/src/content/docs/de/5x/starter/installing.mdx index 8c681f1628..dfcd4b7c1a 100644 --- a/src/content/docs/de/5x/starter/installing.mdx +++ b/src/content/docs/de/5x/starter/installing.mdx @@ -70,7 +70,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/de/5x/starter/static-files.mdx b/src/content/docs/de/5x/starter/static-files.mdx index abb2ac3d09..48ce27ccba 100644 --- a/src/content/docs/de/5x/starter/static-files.mdx +++ b/src/content/docs/de/5x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Verstehen Sie, wie Sie statische Dateien wie Bilder, CSS und JavaSc --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Um statische Dateien wie Bilder, CSS-Dateien und JavaScript-Dateien bereitzustellen, verwenden Sie die in Express integrierte Middleware-Funktion `express.static`. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + Weitere Informationen über die `serve-static` Funktion und ihre Optionen finden Sie unter [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/es/4x/guide/debugging.mdx b/src/content/docs/es/4x/guide/debugging.mdx index 130a69b697..64f474746e 100644 --- a/src/content/docs/es/4x/guide/debugging.mdx +++ b/src/content/docs/es/4x/guide/debugging.mdx @@ -4,6 +4,7 @@ description: Aprenda cómo habilitar y utilizar los registros de depuración en --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; Para ver todos los registros internos usados en Express, establece la variable de entorno `DEBUG` a `express:*` al ejecutar tu aplicación. @@ -86,22 +87,119 @@ Cuando se hace una solicitud a la aplicación, verá los registros especificados Para ver los registros sólo desde la implementación del router, establece el valor de `DEBUG` a `express:router`. De la misma manera, para ver los registros sólo desde la implementación de la aplicación, establece el valor de `DEBUG` a `express:application`, y así sucesivamente. -## Aplicaciones generadas por `express` +## Using `debug` in your own code -Una aplicación generada por el comando `express` utiliza el módulo `debug` y su espacio de nombres de depuración está cubierto por el nombre de la aplicación. +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: -Por ejemplo, si generaste la aplicación con \`$ muestra expresa, puedes habilitar las declaraciones de depuración con el siguiente comando: + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; + +const debug = debugModule('myapp:server'); +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` Puede especificar más de un espacio de nombres de depuración asignando una lista de nombres separados por comas: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,express:router node index.js +``` + +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*" } +} ``` +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Opciones avanzadas Cuando se ejecuta a través de Node.js, puede establecer algunas variables de entorno que cambiarán el comportamiento del registro de depuración: diff --git a/src/content/docs/es/4x/guide/error-handling.mdx b/src/content/docs/es/4x/guide/error-handling.mdx index 2214f84e19..1f2c9bde9f 100644 --- a/src/content/docs/es/4x/guide/error-handling.mdx +++ b/src/content/docs/es/4x/guide/error-handling.mdx @@ -62,14 +62,16 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -A partir de Express 5, manejadores de rutas y middleware que devuelven una Promise -llamará automáticamente a `next(value)` cuando rechacen o lancen un error. -Por ejemplo: +Errors from rejected promises are not passed to `next` automatically, and this includes `async` functions: if an `async` route handler throws or awaits a rejected promise, the rejection is unhandled, which crashes the process on current Node.js versions. You must catch the error yourself and pass it to Express: ```js app.get('/user/:id', async (req, res, next) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` @@ -77,14 +79,22 @@ app.get('/user/:id', async (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` -Si `getUserById` arroja un error o rechaza, `next` será llamado con -el error arrojado o el valor rechazado. Si no se proporciona ningún valor rechazado, `next` -será llamado con un objeto de Error predeterminado proporcionado por el enrutador Express. + + +Consider [updating to Express 5](/guide/migrating-5), where route handlers and middleware that +return a Promise call `next(value)` automatically when they reject or throw an error, making the +`try...catch` above unnecessary. + + If you pass anything to the `next()` function (except the string `'route'`), Express regards the current request as being an error and will skip any @@ -180,9 +190,7 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Since promises automatically catch both synchronous errors and rejected promises, -you can simply provide `next` as the final catch handler and Express will catch errors, -because the catch handler is given the error as the first argument. +If a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, passing `next` as the handler is enough: `.catch` calls it with the error as its first argument, which is exactly the argument `next` expects, so the error reaches Express. También podría utilizar una cadena de manejadores para depender de la captura de errores sincrónicos , reduciendo el código asincrónico a algo trivial. Por ejemplo: @@ -219,8 +227,8 @@ app.get('/', [ ]); ``` -El ejemplo anterior tiene un par de declaraciones triviales de la llamada `readFile` -. Si `readFile` causa un error, entonces pasa el error a Express, de lo contrario +The above example contains a couple of trivial statements following the `readFile` +call. Si `readFile` causa un error, entonces pasa el error a Express, de lo contrario regresa rápidamente al mundo del manejo sincrónico de errores en el siguiente manejador en la cadena. Luego, el ejemplo anterior intenta procesar los datos. Si esto falla, entonces el gestor de errores sincrónico lo capturará. Si hubiera hecho este procesamiento dentro de @@ -424,7 +432,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) También en este ejemplo, `clientErrorHandler` se define de la siguiente manera; en este caso, el error se pasa explícitamente al siguiente. -Tenga en cuenta que cuando _no_ llama "siguiente" en una función de manejo de errores, usted es responsable de escribir (y terminar) la respuesta. De lo contrario, esas solicitudes se "colgarán" y no serán elegibles para la recolección de basura. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. De lo contrario, esas solicitudes se "colgarán" y no serán elegibles para la recolección de basura. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/es/4x/guide/overriding-express-api.mdx b/src/content/docs/es/4x/guide/overriding-express-api.mdx index f400b7a3b5..0a8427982c 100644 --- a/src/content/docs/es/4x/guide/overriding-express-api.mdx +++ b/src/content/docs/es/4x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -La API Express consiste en varios métodos y propiedades sobre los objetos de solicitud y respuesta. Estos son heredados por prototipo. Hay dos puntos de extensión para la API Express: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. Estos son heredados por prototipo. Hay dos puntos de extensión para la API Express: 1. Los prototipos globales en `express.request` y `express.response`. 2. prototipos específicos de la aplicación en `app.request` y `app.response`. diff --git a/src/content/docs/es/4x/guide/routing.mdx b/src/content/docs/es/4x/guide/routing.mdx index da62b46497..35789659c0 100644 --- a/src/content/docs/es/4x/guide/routing.mdx +++ b/src/content/docs/es/4x/guide/routing.mdx @@ -13,7 +13,7 @@ por ejemplo, `app. et()` para manejar solicitudes GET y `app.post` para manejar see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. En otras palabras, la aplicación "escucha" para peticiones que coinciden con el/los método(s) especificado(s), y cuando detecta una coincidencia, llama a la función de callback especificada. +En otras palabras, la aplicación "escucha" para peticiones que coinciden con el/los método(s) especificado(s), y cuando detecta una coincidencia, llama a la función de callback especificada. En otras palabras, la aplicación "escucha" para peticiones que coinciden con el/los método(s) especificado(s), y cuando detecta una coincidencia, llama a la función de callback especificada. De hecho, los métodos de enrutamiento pueden tener más de una función de callback como argumentos. Con múltiples funciones de callback, es importante proporcionar `next` como un argumento a la función de callback y luego llamar `next()` dentro del cuerpo de la función para desactivar el control @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express soporta métodos que corresponden a todos los métodos de petición HTTP: `get`, `post`, y así sucesivamente. For a full list, see [app.METHOD](/api/application#appmethod). -Hay un método especial de enrutamiento, `app.all()`, usado para cargar funciones de middleware en una ruta para _all_ métodos de petición HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +Hay un método especial de enrutamiento, `app.all()`, usado para cargar funciones de middleware en una ruta para _all_ métodos de petición HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Rutas de ruta -Las rutas de ruta, en combinación con un método de solicitud, definen los extremos en los que se pueden realizar las solicitudes. Las rutas pueden ser cadenas, patrones de cadenas o expresiones regulares. +Las rutas de ruta, en combinación con un método de solicitud, definen los extremos en los que se pueden realizar las solicitudes. Las rutas pueden ser cadenas, patrones de cadenas o expresiones regulares. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -235,6 +235,26 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => { }); ``` +A wildcard (`*`) on its own matches anything at its position, including entire subpaths. For example, this route path will match `/file/style.css` as well as `/file/javascripts/jquery.js`. Wildcards are unnamed, so the matched value is available as `req.params[0]` instead of a named parameter. + +```js +app.get('/file/*', (req, res) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/file/*', (req: Request, res: Response) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + ### Rutas de ruta basadas en expresiones regulares @@ -348,6 +368,14 @@ caracteres con una barra inversa adicional, por ejemplo `\d+`. The [`*`](https://github.com/expressjs/express/issues/2495) character in regular expressions is not interpreted in the usual way. Como un workaround, usa `{0,}` en lugar de `*`. +Unlike named route parameters, wildcard (`*`) matches in [string patterns](#route-paths-based-on-string-patterns) and capture groups in regular expressions are unnamed: their values are available by position, as `req.params[0]`, `req.params[1]`, and so on. + +``` +Route path: /file/*/size/* +Request URL: http://localhost:3000/file/javascripts/jquery.js/size/large +req.params: { "0": "javascripts/jquery.js", "1": "large" } +``` + ## Manejadores de rutas Puedes proporcionar múltiples funciones de callback que se comportan como [middleware](/guide/using-middleware) para gestionar una solicitud. La única excepción es que estos callbacks podrían invocar a `next('route')` para evitar las llamadas restantes de ruta. Se puede utilizar este mecanismo para imponer condiciones previas a una ruta, luego pasar el control a las rutas posteriores si no hay razón para proceder con la ruta actual. @@ -387,7 +415,7 @@ En este ejemplo: Los manejadores de rutas pueden ser en forma de una función, un array de funciones o combinaciones de ambos, como se muestra en los siguientes ejemplos. -Una única función de callback puede manejar una ruta. Por ejemplo: +Más de una función de callback puede manejar una ruta (asegúrese de especificar el objeto `siguiente`). Por ejemplo: ```js app.get('/example/a', (req, res) => { @@ -403,7 +431,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -Más de una función de callback puede manejar una ruta (asegúrese de especificar el objeto `siguiente`). Por ejemplo: +Una combinación de funciones independientes y arreglos de funciones puede manejar una ruta. Por ejemplo: ```js app.get( @@ -527,7 +555,7 @@ app.get( ## Métodos de respuesta -Los métodos en el objeto de respuesta (`res`) en la siguiente tabla pueden enviar una respuesta al cliente y terminar el ciclo de solicitud y respuesta. Si ninguno de estos métodos es llamado desde un gestor de rutas, la petición del cliente se dejará colgada. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. Si ninguno de estos métodos es llamado desde un gestor de rutas, la petición del cliente se dejará colgada.| Method | Description | Método | Descripción | | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | @@ -544,7 +572,7 @@ Los métodos en el objeto de respuesta (`res`) en la siguiente tabla pueden envi ## app.route() Puede crear manejadores de rutas encadenables para una ruta usando `app.route()`. -Debido a que la ruta se especifica en una única ubicación, la creación de rutas modulares es útil, al igual que la reducción de redundancia y tipografías. Para más información sobre rutas, vea: [documentación Router() ](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router). Aquí hay un ejemplo de manejadores encadenados de rutas que se definen usando `app.route()`. @@ -580,9 +608,9 @@ app ## express.Router -Utilice la clase `express.Router` para crear manejadores modulares de rutas. Una instancia de `Router` es un sistema completo de middleware y enrutamiento; por esta razón, a menudo se le denomina "mini-app". +Utilice la clase `express.Router` para crear manejadores modulares de rutas. Una instancia de `Router` es un sistema completo de middleware y enrutamiento; por esta razón, a menudo se le denomina "mini-app".The following example creates a router as a module, loads a middlew -El siguiente ejemplo crea un router como módulo, carga una función de middleware en él, define algunas rutas y monta el módulo del router en una ruta de la aplicación principal. +El siguiente ejemplo crea un router como módulo, carga una función de middleware en él, define algunas rutas y monta el módulo del router en una ruta de la aplicación principal.Create a router file named `birds.js` in the app directory, with th Crea un archivo de enrutador llamado `birds.js` en el directorio de la aplicación, con el siguiente contenido: @@ -677,7 +705,7 @@ app.use('/birds', birds); La aplicación ahora será capaz de manejar solicitudes a `/birds` y `/birds/about`, así como llamar a la función de middleware `timeLog` que es específica de la ruta. -Pero si la ruta padre `/birds` tiene parámetros de ruta, no será accesible por defecto desde las subrutas. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +Pero si la ruta padre `/birds` tiene parámetros de ruta, no será accesible por defecto desde las subrutas. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter). ```js const router = express.Router({ mergeParams: true }); diff --git a/src/content/docs/es/4x/guide/using-middleware.mdx b/src/content/docs/es/4x/guide/using-middleware.mdx index d549df50b2..27c66159f4 100644 --- a/src/content/docs/es/4x/guide/using-middleware.mdx +++ b/src/content/docs/es/4x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Aprenda cómo usar middleware en aplicaciones Express.js, incluyend import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express es un framework web de enrutamiento y middleware que tiene una funcionalidad mínima propia: Una aplicación Express es esencialmente una serie de llamadas a funciones de middleware. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -Las funciones _Middleware_ son funciones que tienen acceso al [objeto de solicitud](/api#req) (`req`), el [objeto de respuesta](/api#res) (`res`), y la siguiente función de middleware en el ciclo de solicitud y respuesta de la aplicación. La siguiente función middleware se denota comúnmente por una variable llamada `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Las funciones de Middleware pueden realizar las siguientes tareas: - Ejecutar cualquier código. -- Realizar cambios en la solicitud y en los objetos de respuesta. +- Modify the request and response objects. - Terminar el ciclo de solicitud de respuesta. -- Llame a la siguiente función de middleware en la pila. +- Pass control to the next middleware function. -Si la función actual de middleware no termina el ciclo de solicitud de respuesta, debe llamar a `next()` para pasar el control a la siguiente función de middleware. De lo contrario, la solicitud quedará colgada. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. De lo contrario, la solicitud quedará colgada. Una aplicación Express puede utilizar los siguientes tipos de middleware: @@ -27,14 +32,15 @@ Una aplicación Express puede utilizar los siguientes tipos de middleware: - [Middleware incorporado](#middleware.built-in) - [Middleware de terceros](#middleware.third-party) -Puede cargar middleware de nivel de aplicación y de enrutador con una ruta de montaje opcional. -También puede cargar una serie de funciones de middleware juntas, lo que crea un substack del sistema de middleware en un punto de montaje. +Puede cargar middleware de nivel de aplicación y de enrutador con una ruta de montaje opcional. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Middleware de nivel de aplicación -Vincular middleware a una instancia del [objeto de aplicación](/api#app) usando `app.use()` y `app. ETHOD()` funciona, donde `METHOD` es el método HTTP de la petición que la función middleware maneja (como GET, PUT o POST) en minúsculas. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -Este ejemplo muestra una función de middleware sin ruta de montaje. La función se ejecuta cada vez que la aplicación recibe una solicitud. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -Este ejemplo muestra una función middleware montada en la ruta `/user/:id`. La función se ejecuta para cualquier tipo de petición -HTTP en la ruta `/user/:id`. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Manejadores de rutas + Este ejemplo muestra una ruta y su función manejadora (middleware system). La función maneja peticiones GET a la ruta `/user/:id`. ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -He aquí un ejemplo de carga de una serie de funciones de middleware en un punto de montaje, con una ruta de montaje. -Ilustra un substack de middleware que imprime la información de la petición para cualquier tipo de petición HTTP a la ruta `/user/:id`. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Los manejadores de rutas le permiten definir múltiples rutas para una ruta. El siguiente ejemplo define dos rutas para peticiones GET a la ruta `/user/:id`. La segunda ruta no causará ningún problema, pero nunca se llamará porque la primera ruta termina el ciclo de solicitud de respuesta. +### Multiple route handlers -Este ejemplo muestra un substack de middleware que maneja peticiones GET a la ruta `/user/:id`. +Los manejadores de rutas le permiten definir múltiples rutas para una ruta. El siguiente ejemplo define dos rutas para peticiones GET a la ruta `/user/:id`. La segunda ruta no causará ningún problema, pero nunca se llamará porque la primera ruta termina el ciclo de solicitud de respuesta. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -Para omitir el resto de las funciones de middleware desde una pila de middleware de router, llame a `next('ruta')` para pasar el control a la siguiente ruta. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ Para omitir el resto de las funciones de middleware desde una pila de middleware -Este ejemplo muestra un substack de middleware que maneja peticiones GET a la ruta `/user/:id`. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Middleware también puede ser declarado en una matriz para reusabilidad. +### Reusable middleware arrays -Este ejemplo muestra una matriz con un substack de middleware que maneja peticiones GET en la ruta `/user/:id` +Middleware functions can also be grouped into arrays for better reusability. Este ejemplo muestra una matriz con un substack de middleware que maneja peticiones GET en la ruta `/user/:id` ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,19 +280,25 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Middleware de nivel remoto -El middleware Router-level funciona de la misma manera que el middleware a nivel de aplicación, excepto que está vinculado a una instancia de `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); ``` +```ts +import express from 'express'; + +const router = express.Router(); +``` + Carga el middleware a nivel de enrutador usando las funciones `router.use()` y `router.METHOD()`. El siguiente código de ejemplo replica el sistema middleware que se muestra arriba para el middleware de nivel de aplicación, mediante el uso de router-level middleware: @@ -313,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -363,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -413,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -434,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -Para omitir el resto de las funciones de middleware del enrutador, llama a `next('router')` -para pasar el control de vuelta fuera de la instancia del enrutador. +### Skipping out of a router -Este ejemplo muestra un substack de middleware que maneja peticiones GET a la ruta `/user/:id`. +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. + +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -506,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Middleware de manejo de errores - - -Middleware manejado por errores siempre toma _four_ argumentos. Debe proporcionar cuatro argumentos para -identificarlo como una función de middleware que maneja errores. Incluso si no necesitas usar el objeto `next` -, debes especificarlo para mantener la firma. De lo contrario, el objeto `siguiente` será -interpretado como middleware regular y fallará al manejar errores. - - - Define las funciones de middleware de la misma manera que otras funciones de middleware, excepto con cuatro argumentos en lugar de tres, específicamente con la firma `(err, req, res, next)`: ```js @@ -533,7 +543,20 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Para más detalles sobre el middleware de manejo de errores, vea: [Gestión de errores](/guide/error-handling). + + +Middleware manejado por errores siempre toma _four_ argumentos. Debe proporcionar cuatro argumentos para +identificarlo como una función de middleware que maneja errores. Incluso si no necesitas usar el objeto `next` +, debes especificarlo para mantener la firma. De lo contrario, el objeto `siguiente` será +interpretado como middleware regular y fallará al manejar errores. + + + + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Middleware incorporado @@ -544,6 +567,8 @@ Express tiene las siguientes funciones de middleware incorporadas: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. - [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTA: Disponible con Express 4.16.0+** +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. **NOTE: Available with Express 4.17.0+** +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. **NOTE: Available with Express 4.17.0+** - [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTA: Disponible con Express 4.16.0+** ## Middleware de terceros @@ -585,4 +610,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Para una lista parcial de funciones de middleware de terceros que se utilizan comúnmente con Express, vea: [Middleware de terceros](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/es/4x/guide/using-template-engines.mdx b/src/content/docs/es/4x/guide/using-template-engines.mdx index 343047c631..aef88abea2 100644 --- a/src/content/docs/es/4x/guide/using-template-engines.mdx +++ b/src/content/docs/es/4x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Utilizando motores de plantillas con Express -description: Descubra cómo integrar y utilizar motores de plantillas como Pug, Handlebars y EJS con Express.js para renderizar páginas HTML dinámicas eficientemente. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ Un _template engine_ le permite usar plantillas estáticas en su aplicación. En en un archivo de plantilla con valores reales. y transforma la plantilla en un archivo HTML enviado al cliente. Este enfoque facilita el diseño de una página HTML. -El [generador de aplicaciones Express](/starter/generator) utiliza [Pug](https://pugjs.org/api/getting-started.html) como predeterminado, pero también soporta [Handlebars](https://www.npmjs.com/package/handlebars), y [EJS](https://www.npmjs.com/package/ejs), entre otros. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `vistas`, el directorio donde están ubicados los archivos de plantilla. Ej: `app.set('vistas', './views')`. Esto por defecto es el directorio `views` en el directorio raíz de la aplicación. - `ver engine`, el motor de plantillas a usar. Por ejemplo, para usar el motor de plantillas Pug: `app.set('view engine', 'pug')`. -A continuación, instale el correspondiente paquete npm del motor de plantillas; por ejemplo para instalar Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ que `res.render()` llama para renderizar el código de plantilla. Algunos motores de plantillas no siguen esta convención. La biblioteca [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) sigue esta convención mapeando todos los motores de plantillas populares de Node.js, y por lo tanto funciona perfectamente dentro de Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/es/4x/guide/writing-middleware.mdx b/src/content/docs/es/4x/guide/writing-middleware.mdx index 166656d486..ae6acc80cc 100644 --- a/src/content/docs/es/4x/guide/writing-middleware.mdx +++ b/src/content/docs/es/4x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Aprenda cómo escribir funciones personalizadas de middleware para --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Además, la función de callback de la ruta raíz utiliza la propiedad que la función middleware añade a `req` (el objeto de la solicitud). La aplicación ahora utiliza la función de middleware `requestTime`. @@ -199,8 +200,8 @@ La función Middleware `myLogger` simplemente imprime un mensaje, luego pasa la ### Tiempo de solicitud de la función Middleware -A continuación, crearemos una función de middleware llamada "requestTime" y agregaremos una propiedad llamada `requestTime` -al objeto de la solicitud. +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -420,9 +421,13 @@ que no sea de manejo de enrutamiento y middleware restante. -Debido a que tiene acceso al objeto de solicitud, el objeto de respuesta, la siguiente función de middleware en la pila, y el nodo entero. s API, las posibilidades con funciones middleware son infinitas. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Para más información sobre middleware exprés, vea: [Usando middleware exprés](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Middleware configurable diff --git a/src/content/docs/es/4x/starter/basic-routing.mdx b/src/content/docs/es/4x/starter/basic-routing.mdx index 912969eebe..ca569b5a6d 100644 --- a/src/content/docs/es/4x/starter/basic-routing.mdx +++ b/src/content/docs/es/4x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Aprenda los fundamentos de la enrutamiento en aplicaciones Express. --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Enrutamiento_ se refiere a determinar cómo responde una aplicación a una solicitud de cliente a un punto final en particular, que es una URI (o ruta) y un método específico de petición HTTP (GET, POST, etc.). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -Para más detalles sobre enrutamiento, vea la [guía de enrutamiento](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/es/4x/starter/faq.mdx b/src/content/docs/es/4x/starter/faq.mdx index 2e3e84ca01..48c0a3a61e 100644 --- a/src/content/docs/es/4x/starter/faq.mdx +++ b/src/content/docs/es/4x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Encuentre respuestas a preguntas frecuentes sobre Express.js, incluyendo temas sobre estructura de aplicaciones, modelos, autenticación, motores de plantillas, manejo de errores, y más. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## ¿Cómo debo estructurar mi aplicación? No hay una respuesta definitiva a esta pregunta. La respuesta depende @@ -42,7 +44,11 @@ Para normalizar las interfaces del motor de plantillas y la caché, consulte el [consolidate.js](https://github.com/visionmedia/consolidate.js) para obtener soporte. Los motores de plantillas no listados pueden seguir soportando la firma Express. -Para obtener más información, consulte [Usar motores de plantilla con Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## ¿Cómo puedo manejar las respuestas 404? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Para más información, vea [Gestión de errores](/en/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## ¿Cómo renderizo HTML plano? diff --git a/src/content/docs/es/4x/starter/installing.mdx b/src/content/docs/es/4x/starter/installing.mdx index e96eb953fa..573304a044 100644 --- a/src/content/docs/es/4x/starter/installing.mdx +++ b/src/content/docs/es/4x/starter/installing.mdx @@ -79,7 +79,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/es/4x/starter/static-files.mdx b/src/content/docs/es/4x/starter/static-files.mdx index 2cf6f3c20f..02619b37a3 100644 --- a/src/content/docs/es/4x/starter/static-files.mdx +++ b/src/content/docs/es/4x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Describa cómo servir archivos estáticos como imágenes, CSS y Jav --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Para servir archivos estáticos como imágenes, archivos CSS, y archivos JavaScript, utiliza la función middleware integrada `express.static` en Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + Para más detalles sobre la función `serve-static` y sus opciones, vea [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/es/5x/guide/debugging.mdx b/src/content/docs/es/5x/guide/debugging.mdx index 130a69b697..7bf1bc0b12 100644 --- a/src/content/docs/es/5x/guide/debugging.mdx +++ b/src/content/docs/es/5x/guide/debugging.mdx @@ -4,104 +4,218 @@ description: Aprenda cómo habilitar y utilizar los registros de depuración en --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -Para ver todos los registros internos usados en Express, establece la variable de entorno `DEBUG` a -`express:*` al ejecutar tu aplicación. +To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*,router,router:*` when launching your app. Routing is handled by the separate [router](https://github.com/pillarjs/router) package, so its logs live under the `router` namespace and are not included in `express:*`. ```bash -$ DEBUG=express:* node index.js +$ DEBUG=express:*,router,router:* node index.js ``` En Windows, utilice el comando correspondiente. ```bash -> $env:DEBUG = "express:*"; node index.js +> $env:DEBUG = "express:*,router,router:*"; node index.js ``` -Ejecutando este comando en la aplicación predeterminada generada por el [generador expreso](/starter/generator) imprime la siguiente salida: +Running this command on a small app with a JSON body parser and a mounted router prints the following output: + +```cjs title="index.cjs" +const express = require('express'); + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` + +```mjs title="index.mjs" +import express from 'express'; + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` ```bash -$ DEBUG=express:* node ./bin/www - express:router:route new / +0ms - express:router:layer new / +1ms - express:router:route get / +1ms - express:router:layer new / +0ms - express:router:route new / +1ms - express:router:layer new / +0ms - express:router:route get / +0ms - express:router:layer new / +0ms - express:application compile etag weak +1ms - express:application compile query parser extended +0ms - express:application compile trust proxy false +0ms - express:application booting in development mode +1ms - express:router use / query +0ms - express:router:layer new / +0ms - express:router use / expressInit +0ms - express:router:layer new / +0ms - express:router use / favicon +1ms - express:router:layer new / +0ms - express:router use / logger +0ms - express:router:layer new / +0ms - express:router use / jsonParser +0ms - express:router:layer new / +1ms - express:router use / urlencodedParser +0ms - express:router:layer new / +0ms - express:router use / cookieParser +0ms - express:router:layer new / +0ms - express:router use / stylus +90ms - express:router:layer new / +0ms - express:router use / serveStatic +0ms - express:router:layer new / +0ms - express:router use / router +0ms - express:router:layer new / +1ms - express:router use /users router +0ms - express:router:layer new /users +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms +$ DEBUG=express:*,router,router:* node index.js + express:application set "x-powered-by" to true +0ms + express:application set "etag" to 'weak' +3ms + express:application set "etag fn" to [Function: generateETag] +0ms + express:application set "env" to 'development' +1ms + express:application set "query parser" to 'simple' +0ms + express:application set "query parser fn" to [Function: parse] +0ms + express:application set "subdomain offset" to 2 +1ms + express:application set "trust proxy" to false +0ms + express:application set "trust proxy fn" to [Function: trustNone] +1ms + express:application booting in development mode +0ms + express:application set "view" to [Function: View] +0ms + express:application set "views" to '/projects/example/views' +1ms + express:application set "jsonp callback name" to 'callback' +0ms + router use '/' jsonParser +0ms + router:layer new '/' +0ms + router:route new '/' +0ms + router:layer new '/' +3ms + router:route get / +0ms + router:layer new '/' +1ms + router use '/users' router +4ms + router:layer new '/users' +0ms + router:route new '/' +1ms + router:layer new '/' +0ms + router:route get / +1ms + router:layer new '/' +1ms ``` Cuando se hace una solicitud a la aplicación, verá los registros especificados en el código Express: ```bash - express:router dispatching GET / +4h - express:router query : / +2ms - express:router expressInit : / +0ms - express:router favicon : / +0ms - express:router logger : / +1ms - express:router jsonParser : / +0ms - express:router urlencodedParser : / +1ms - express:router cookieParser : / +0ms - express:router stylus : / +0ms - express:router serveStatic : / +2ms - express:router router : / +2ms - express:router dispatching GET / +1ms - express:view lookup "index.pug" +338ms - express:view stat "/projects/example/views/index.pug" +0ms - express:view render "/projects/example/views/index.pug" +1ms + router dispatching GET /users +712ms + router jsonParser : /users +1ms + router trim prefix (/users) from url /users +2ms + router router /users : /users +0ms + router dispatching GET / +0ms +``` + +To see the logs only from the router implementation, set the value of `DEBUG` to `router,router:*`. De la misma manera, para ver los registros sólo desde la implementación de la aplicación, establece el valor de `DEBUG` a `express:application`, y así sucesivamente. + +## Using `debug` in your own code + +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: + + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); ``` -Para ver los registros sólo desde la implementación del router, establece el valor de `DEBUG` a `express:router`. De la misma manera, para ver los registros sólo desde la implementación de la aplicación, establece el valor de `DEBUG` a `express:application`, y así sucesivamente. +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; -## Aplicaciones generadas por `express` +const debug = debugModule('myapp:server'); +const app = express(); -Una aplicación generada por el comando `express` utiliza el módulo `debug` y su espacio de nombres de depuración está cubierto por el nombre de la aplicación. +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); -Por ejemplo, si generaste la aplicación con \`$ muestra expresa, puedes habilitar las declaraciones de depuración con el siguiente comando: +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` Puede especificar más de un espacio de nombres de depuración asignando una lista de nombres separados por comas: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,router node index.js ``` +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*,router,router:*" } +} +``` + +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Opciones avanzadas Cuando se ejecuta a través de Node.js, puede establecer algunas variables de entorno que cambiarán el comportamiento del registro de depuración: diff --git a/src/content/docs/es/5x/guide/error-handling.mdx b/src/content/docs/es/5x/guide/error-handling.mdx index b81bd4041b..ff03c4907a 100644 --- a/src/content/docs/es/5x/guide/error-handling.mdx +++ b/src/content/docs/es/5x/guide/error-handling.mdx @@ -14,6 +14,8 @@ occur both synchronously and asynchronously. Express viene con un manejador de e Es importante asegurarse de que Express capture todos los errores que ocurren mientras ejecuta los manejadores de rutas y el middleware. +### Errors in synchronous code + Los errores que ocurren en el código sincrónico dentro de los manejadores de rutas y middleware no requieren trabajo extra. Si el código sincrónico arroja un error, entonces Express hará capturarlo y procesarlo. Por ejemplo: @@ -32,51 +34,24 @@ app.get('/', (req: Request, res: Response) => { }); ``` -Para los errores devueltos por funciones asincrónicas invocadas por los manejadores de rutas -y middleware, debes pasarlos a la función `next()`, donde Express las capturará y procesará -. Por ejemplo: - -```js -app.get('/', (req, res, next) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` +### Errors in asynchronous code -```ts -import { type Request, type Response, type NextFunction } from 'express'; - -app.get('/', (req: Request, res: Response, next: NextFunction) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` - -A partir de Express 5, manejadores de rutas y middleware que devuelven una Promise -llamará automáticamente a `next(value)` cuando rechacen o lancen un error. -Por ejemplo: +The recommended way to write asynchronous handlers is with `async` functions. +Route handlers and middleware that return a Promise call `next(value)` +automatically when they reject or throw an error, and `async` functions always +return a Promise, so their errors reach Express with no extra work. Por ejemplo: ```js -app.get('/user/:id', async (req, res, next) => { +app.get('/user/:id', async (req, res) => { const user = await getUserById(req.params.id); res.send(user); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', async (req: Request, res: Response) => { const user = await getUserById(req.params.id); res.send(user); }); @@ -90,49 +65,41 @@ If you pass anything to the `next()` function (except the string `'route'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. -Si la devolución de llamada en una secuencia no proporciona datos, sólo errores, puede simplificar -este código de la siguiente manera: +### Working with promise chains + +If you build a promise chain instead of using an `async` function, return the +promise from the handler and Express will likewise call `next` automatically +when it rejects: ```js -app.get('/', [ - function (req, res, next) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req, res) { - res.send('OK'); - }, -]); +app.get('/', (req, res) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/', [ - function (req: Request, res: Response, next: NextFunction) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req: Request, res: Response) { - res.send('OK'); - }, -]); +app.get('/', (req: Request, res: Response) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` -En el ejemplo anterior, `next` es proporcionado como el callback para `fs.writeFile`, -que es llamado con o sin errores. Si no hay error, se ejecuta el segundo manejador -, de lo contrario Express catches y procesa el error. - -Debe capturar errores que ocurren en código asíncrono invocado por manejadores de ruta o un middleware -y pasarlos a Express para su procesamiento. Por ejemplo: +If the promise is not returned, Express does not know it exists, and you must +route the error yourself by providing `next` as the final catch handler. +Without it, the rejection would be unhandled and crash the process: ```js app.get('/', (req, res, next) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` @@ -140,31 +107,32 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` -El ejemplo anterior utiliza un bloque `try...catch` para capturar errores en el código asincrónico -y pasarlos a Express. Si el bloque `try...catch` -fuera omitido, Express no capturaría el error ya que no es parte del código de manejador -sincrónico. +This works because if a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, `.catch` calls its handler with the error as the first argument, which is exactly the argument `next` expects, so the error reaches Express. -Usa promesas para evitar la sobrecarga del bloque "intentar...atrapar" o al usar funciones -que devuelven promesas. Por ejemplo: +### Working with callback APIs + +Errors produced by callback-based APIs, such as those in `node:fs`, are not +thrown and are not part of any promise. The callback receives them as its first +argument, and you must pass them to the `next()` function yourself, where +Express will catch and process them. Por ejemplo: ```js app.get('/', (req, res, next) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` @@ -172,17 +140,46 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` -Since promises automatically catch both synchronous errors and rejected promises, -you can simply provide `next` as the final catch handler and Express will catch errors, -because the catch handler is given the error as the first argument. +Si la devolución de llamada en una secuencia no proporciona datos, sólo errores, puede simplificar +este código de la siguiente manera: + +```js +app.get('/', [ + function (req, res, next) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req, res) { + res.send('OK'); + }, +]); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', [ + function (req: Request, res: Response, next: NextFunction) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req: Request, res: Response) { + res.send('OK'); + }, +]); +``` + +En el ejemplo anterior, `next` es proporcionado como el callback para `fs.writeFile`, +que es llamado con o sin errores. Si no hay error, se ejecuta el segundo manejador +, de lo contrario Express catches y procesa el error. También podría utilizar una cadena de manejadores para depender de la captura de errores sincrónicos , reduciendo el código asincrónico a algo trivial. Por ejemplo: @@ -219,14 +216,49 @@ app.get('/', [ ]); ``` -El ejemplo anterior tiene un par de declaraciones triviales de la llamada `readFile` -. Si `readFile` causa un error, entonces pasa el error a Express, de lo contrario +The above example contains a couple of trivial statements following the `readFile` +call. Si `readFile` causa un error, entonces pasa el error a Express, de lo contrario regresa rápidamente al mundo del manejo sincrónico de errores en el siguiente manejador en la cadena. Luego, el ejemplo anterior intenta procesar los datos. Si esto falla, entonces el gestor de errores sincrónico lo capturará. Si hubiera hecho este procesamiento dentro de el callback `readFile`, entonces la aplicación podría salir y los manejadores de error Express no se ejecutarían. +Finally, for asynchronous code that provides no error-first callback, such as a +timer, catch errors inside the asynchronous code itself and pass them to +Express: + +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', (req: Request, res: Response, next: NextFunction) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +El ejemplo anterior utiliza un bloque `try...catch` para capturar errores en el código asincrónico +y pasarlos a Express. Si el bloque `try...catch` +fuera omitido, Express no capturaría el error ya que no es parte del código de manejador +sincrónico. + Whichever method you use, if you want Express error handlers to be called in and the application to survive, you must ensure that Express receives the error. @@ -424,7 +456,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) También en este ejemplo, `clientErrorHandler` se define de la siguiente manera; en este caso, el error se pasa explícitamente al siguiente. -Tenga en cuenta que cuando _no_ llama "siguiente" en una función de manejo de errores, usted es responsable de escribir (y terminar) la respuesta. De lo contrario, esas solicitudes se "colgarán" y no serán elegibles para la recolección de basura. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. De lo contrario, esas solicitudes se "colgarán" y no serán elegibles para la recolección de basura. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/es/5x/guide/overriding-express-api.mdx b/src/content/docs/es/5x/guide/overriding-express-api.mdx index f400b7a3b5..0a8427982c 100644 --- a/src/content/docs/es/5x/guide/overriding-express-api.mdx +++ b/src/content/docs/es/5x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -La API Express consiste en varios métodos y propiedades sobre los objetos de solicitud y respuesta. Estos son heredados por prototipo. Hay dos puntos de extensión para la API Express: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. Estos son heredados por prototipo. Hay dos puntos de extensión para la API Express: 1. Los prototipos globales en `express.request` y `express.response`. 2. prototipos específicos de la aplicación en `app.request` y `app.response`. diff --git a/src/content/docs/es/5x/guide/routing.mdx b/src/content/docs/es/5x/guide/routing.mdx index fc9c345c22..fcae30f416 100644 --- a/src/content/docs/es/5x/guide/routing.mdx +++ b/src/content/docs/es/5x/guide/routing.mdx @@ -13,7 +13,7 @@ por ejemplo, `app. et()` para manejar solicitudes GET y `app.post` para manejar see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. En otras palabras, la aplicación "escucha" para peticiones que coinciden con el/los método(s) especificado(s), y cuando detecta una coincidencia, llama a la función de callback especificada. +En otras palabras, la aplicación "escucha" para peticiones que coinciden con el/los método(s) especificado(s), y cuando detecta una coincidencia, llama a la función de callback especificada. En otras palabras, la aplicación "escucha" para peticiones que coinciden con el/los método(s) especificado(s), y cuando detecta una coincidencia, llama a la función de callback especificada. De hecho, los métodos de enrutamiento pueden tener más de una función de callback como argumentos. Con múltiples funciones de callback, es importante proporcionar `next` como un argumento a la función de callback y luego llamar `next()` dentro del cuerpo de la función para desactivar el control @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express soporta métodos que corresponden a todos los métodos de petición HTTP: `get`, `post`, y así sucesivamente. For a full list, see [app.METHOD](/api/application#appmethod). -Hay un método especial de enrutamiento, `app.all()`, usado para cargar funciones de middleware en una ruta para _all_ métodos de petición HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +Hay un método especial de enrutamiento, `app.all()`, usado para cargar funciones de middleware en una ruta para _all_ métodos de petición HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Rutas de ruta -Las rutas de ruta, en combinación con un método de solicitud, definen los extremos en los que se pueden realizar las solicitudes. Las rutas de ruta pueden ser cadenas o expresiones regulares. +Las rutas de ruta, en combinación con un método de solicitud, definen los extremos en los que se pueden realizar las solicitudes. Las rutas de ruta pueden ser cadenas o expresiones regulares. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -153,77 +153,9 @@ app.get('/random.text', (req: Request, res: Response) => { }); ``` -### Wildcards - -Los comodines coinciden con cualquier ruta después de un prefijo. Deben tener un nombre, al igual que los parámetros de la ruta, y son capturados como matrices de segmentos de ruta. - -```js -app.get('/files/*filepath', (req, res) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -Para coincidir también con la ruta de la raíz, envuelve el comodín entre llaves: - -```js -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req, res) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req: Request, res: Response) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -### Segmentos opcionales - -Use llaves para definir segmentos opcionales en una ruta de ruta. Cuando el segmento no está presente, el parámetro se omite de `req.params`. - -```js -app.get('/:file{.:ext}', (req, res) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/:file{.:ext}', (req: Request, res: Response) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -Los caracteres `?`, `+`, `*`, `[]`, y `()` están reservados y no pueden usarse como caracteres literales en rutas de ruta. Usa `\` para escapar de ellos si es necesario. +The characters `?`, `+`, `*`, `[]`, `()`, and `!` are reserved and cannot be used as literal characters in route paths, and braces are reserved for [optional segments](#optional-segments). Usa `\` para escapar de ellos si es necesario. @@ -259,7 +191,11 @@ app.get(/.*fly$/, (req: Request, res: Response) => { ## Parámetros de ruta -Los parámetros de ruta se llaman segmentos de URL que se utilizan para capturar los valores especificados en su posición en la URL. Los valores capturados son poblados en el objeto `req.params`, con el nombre del parámetro de ruta especificado en la ruta como sus claves respectivas. +Los parámetros de ruta se llaman segmentos de URL que se utilizan para capturar los valores especificados en su posición en la URL. Los valores capturados son poblados en el objeto `req.params`, con el nombre del parámetro de ruta especificado en la ruta como sus claves respectivas. They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces. + +### Named parameters + +Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below. ``` Route path: /users/:userId/books/:bookId @@ -293,7 +229,7 @@ app.get('/users/:userId/books/:bookId', sendParams); -El nombre de los parámetros de la ruta debe estar compuesto de "caracteres de palabra" ([A-Za-z0-9_]). +The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example `:"user-name"`. @@ -313,14 +249,122 @@ req.params: { "genus": "Prunus", "species": "persica" } -Los caracteres de expresión regular no están soportados en las rutas de ruta. Utilice un array de rutas o expresiones regulares en su lugar. +Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as `:userId(\d+)`. Use an array of paths or a full regular expression instead. Vea la [sintaxis de coincidencia de ruta de ruta](/guide/migrating-5#path-syntax) para más información. +### Wildcards + +Los comodines coinciden con cualquier ruta después de un prefijo. Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string. + +```js +app.get('/files/*filepath', (req, res) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +Para coincidir también con la ruta de la raíz, envuelve el comodín entre llaves: + +```js +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req, res) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req: Request, res: Response) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +### Segmentos opcionales + +Use llaves para definir segmentos opcionales en una ruta de ruta. Cuando el segmento no está presente, el parámetro se omite de `req.params`. + +```js +app.get('/:file{.:ext}', (req, res) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/:file{.:ext}', (req: Request, res: Response) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters: + +```js +app.get('/user/\{:id}', (req, res) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req, res) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/user/\{:id}', (req: Request, res: Response) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req: Request, res: Response) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +No confundas la posición de la barra en la ruta con la [configuración `strict routing`](/api/application/#application-settings), que trata sobre la URL de la solicitud: controla si una URL que termina en barra sigue coincidiendo cuando la ruta no la exige. Por ejemplo, una solicitud a `/order/` coincide con la ruta `/order{/:id}` por defecto, pero devuelve un error 404 cuando strict routing está habilitado; la barra final de `/user/` no se ve afectada porque la ruta `/user/\{:id}` la exige. Todas las solicitudes comentadas en los ejemplos anteriores se comportan igual independientemente de esa configuración.## Route handlersYou can provide multiple callback functions that + ## Manejadores de rutas -Puedes proporcionar múltiples funciones de callback que se comportan como [middleware](/guide/using-middleware) para gestionar una solicitud. La única excepción es que estos callbacks podrían invocar a `next('route')` para evitar las llamadas restantes de ruta. Se puede utilizar este mecanismo para imponer condiciones previas a una ruta, luego pasar el control a las rutas posteriores si no hay razón para proceder con la ruta actual. +Puedes proporcionar múltiples funciones de callback que se comportan como [middleware](/guide/using-middleware) para gestionar una solicitud. La única excepción es que estos callbacks podrían invocar a `next('route')` para evitar las llamadas restantes de ruta. Se puede utilizar este mecanismo para imponer condiciones previas a una ruta, luego pasar el control a las rutas posteriores si no hay razón para proceder con la ruta actual.```js +app.get('/user/:id', (req, res, next) => { +if (req.params.i + +```` ```js app.get('/user/:id', (req, res, next) => { @@ -333,7 +377,7 @@ app.get('/user/:id', (req, res, next) => { app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0'); }); -``` +```` ```ts import { type Request, type Response, type NextFunction } from 'express'; @@ -355,15 +399,17 @@ En este ejemplo: - `GET /user/5` → manejado por primera ruta → envía "Usuario 5" - `GET /user/0` → primera ruta llama a `next('ruta')`, saltando a la siguiente ruta `/user/:id` -Los manejadores de rutas pueden ser en forma de una función, un array de funciones o combinaciones de ambos, como se muestra en los siguientes ejemplos. +Los manejadores de rutas pueden ser en forma de una función, un array de funciones o combinaciones de ambos, como se muestra en los siguientes ejemplos.A single callback function can handle a route. For example:```js + +```` -Una única función de callback puede manejar una ruta. Por ejemplo: +Más de una función de callback puede manejar una ruta (asegúrese de especificar el objeto `siguiente`). ```js app.get('/example/a', (req, res) => { res.send('Hello from A!'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -373,7 +419,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -Más de una función de callback puede manejar una ruta (asegúrese de especificar el objeto `siguiente`). Por ejemplo: +Una combinación de funciones independientes y arreglos de funciones puede manejar una ruta. Por ejemplo: ```js app.get( @@ -403,7 +449,7 @@ app.get( ); ``` -Una matriz de funciones de callback puede manejar una ruta. Por ejemplo: +Una matriz de funciones de callback puede manejar una ruta. ```js const cb0 = function (req, res, next) { @@ -497,26 +543,32 @@ app.get( ## Métodos de respuesta -Los métodos en el objeto de respuesta (`res`) en la siguiente tabla pueden enviar una respuesta al cliente y terminar el ciclo de solicitud y respuesta. Si ninguno de estos métodos es llamado desde un gestor de rutas, la petición del cliente se dejará colgada. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. Si ninguno de estos métodos es llamado desde un gestor de rutas, la petición del cliente se dejará colgada.| Method | Description| Method | Description -| Método | Descripción | -| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -| [res.download()](/api/response#resdownload) | Solicitar un archivo para ser descargado. | -| [res.end()](/api/response#resend) | Terminar el proceso de respuesta. | -| [res.json()](/api/response#resjson) | Enviar una respuesta JSON. | -| [res.jsonp()](/api/response#resjsonp) | Envía una respuesta JSON con soporte JSONP. | -| [res.redirect()](/api/response#resredirect) | Redirigir una solicitud. | -| [res.render()](/api/response#resrender) | Procesar una plantilla de vista. | -| [res.send()](/api/response#ressend) | Enviar una respuesta de varios tipos. | -| [res.sendFile()](/api/response#ressendfile) | Enviar un archivo como un flujo de octet. | -| [res.sendStatus()](/api/response#ressendstatus) | Establece el código de estado de respuesta y envía su representación de cadena como el cuerpo de respuesta. | +| | | +| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/api/response#resdownload) | Solicitar un archivo para ser descargado. | +| [res.end()](/api/response#resend) | Terminar el proceso de respuesta. | +| [res.json()](/api/response#resjson) | Enviar una respuesta JSON. | +| [res.jsonp()](/api/response#resjsonp) | Envía una respuesta JSON con soporte JSONP. | +| | Redirigir una solicitud. | +| [res.render()](/api/response#resrender) | Procesar una plantilla de vista. | +| [res.send()](/api/response#ressend) | Enviar una respuesta de varios tipos. | +| [res.sendFile()](/api/response#ressendfile) | Enviar un archivo como un flujo de octet. | +| [res.sendStatus()](/api/response#ressendstatus) | Establece el código de estado de respuesta y envía su representación de cadena como el cuerpo de respuesta. \|## app.route()You can create chainable route handlers for a rou | ## app.route() Puede crear manejadores de rutas encadenables para una ruta usando `app.route()`. -Debido a que la ruta se especifica en una única ubicación, la creación de rutas modulares es útil, al igual que la reducción de redundancia y tipografías. Para más información sobre rutas, vea: [documentación Router() ](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router).Here is an example of chained route handlers that are defined by us + +Aquí hay un ejemplo de manejadores encadenados de rutas que se definen usando `app.route()`.```js +app +.route('/book') +.get((req, res) => { +res.send('Ge -Aquí hay un ejemplo de manejadores encadenados de rutas que se definen usando `app.route()`. +```` ```js app @@ -530,7 +582,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -550,9 +602,9 @@ app ## express.Router -Utilice la clase `express.Router` para crear manejadores modulares de rutas. Una instancia de `Router` es un sistema completo de middleware y enrutamiento; por esta razón, a menudo se le denomina "mini-app". +Utilice la clase `express.Router` para crear manejadores modulares de rutas. Una instancia de `Router` es un sistema completo de middleware y enrutamiento; por esta razón, a menudo se le denomina "mini-app".The following example creates a router as a module, loads a middlewThe following example creates a router as a module, loads a middlew -El siguiente ejemplo crea un router como módulo, carga una función de middleware en él, define algunas rutas y monta el módulo del router en una ruta de la aplicación principal. +El siguiente ejemplo crea un router como módulo, carga una función de middleware en él, define algunas rutas y monta el módulo del router en una ruta de la aplicación principal.Create a router file named `birds.js` in the app directory, with thCreate a router file named `birds.js` in the app directory, with th Crea un archivo de enrutador llamado `birds.js` en el directorio de la aplicación, con el siguiente contenido: @@ -645,10 +697,13 @@ import birds from './birds'; app.use('/birds', birds); ``` -La aplicación ahora será capaz de manejar solicitudes a `/birds` y `/birds/about`, así como llamar a la función de middleware `timeLog` que es específica de la ruta. +La aplicación ahora será capaz de manejar solicitudes a `/birds` y `/birds/about`, así como llamar a la función de middleware `timeLog` que es específica de la ruta.But if the parent route `/birds` has path parameters, it will not b -Pero si la ruta padre `/birds` tiene parámetros de ruta, no será accesible por defecto desde las subrutas. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +Pero si la ruta padre `/birds` tiene parámetros de ruta, no será accesible por defecto desde las subrutas. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter).```js +const router = express.Router({ mergeParams: true }); + +```` ```js const router = express.Router({ mergeParams: true }); -``` +```` diff --git a/src/content/docs/es/5x/guide/using-middleware.mdx b/src/content/docs/es/5x/guide/using-middleware.mdx index 7a37cd16c1..2590350d31 100644 --- a/src/content/docs/es/5x/guide/using-middleware.mdx +++ b/src/content/docs/es/5x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Aprenda cómo usar middleware en aplicaciones Express.js, incluyend import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express es un framework web de enrutamiento y middleware que tiene una funcionalidad mínima propia: Una aplicación Express es esencialmente una serie de llamadas a funciones de middleware. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -Las funciones _Middleware_ son funciones que tienen acceso al [objeto de solicitud](/api#req) (`req`), el [objeto de respuesta](/api#res) (`res`), y la siguiente función de middleware en el ciclo de solicitud y respuesta de la aplicación. La siguiente función middleware se denota comúnmente por una variable llamada `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Las funciones de Middleware pueden realizar las siguientes tareas: - Ejecutar cualquier código. -- Realizar cambios en la solicitud y en los objetos de respuesta. +- Modify the request and response objects. - Terminar el ciclo de solicitud de respuesta. -- Llame a la siguiente función de middleware en la pila. +- Pass control to the next middleware function. -Si la función actual de middleware no termina el ciclo de solicitud de respuesta, debe llamar a `next()` para pasar el control a la siguiente función de middleware. De lo contrario, la solicitud quedará colgada. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. De lo contrario, la solicitud quedará colgada. Una aplicación Express puede utilizar los siguientes tipos de middleware: @@ -27,14 +32,15 @@ Una aplicación Express puede utilizar los siguientes tipos de middleware: - [Middleware incorporado](#middleware.built-in) - [Middleware de terceros](#middleware.third-party) -Puede cargar middleware de nivel de aplicación y de enrutador con una ruta de montaje opcional. -También puede cargar una serie de funciones de middleware juntas, lo que crea un substack del sistema de middleware en un punto de montaje. +Puede cargar middleware de nivel de aplicación y de enrutador con una ruta de montaje opcional. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Middleware de nivel de aplicación -Vincular middleware a una instancia del [objeto de aplicación](/api#app) usando `app.use()` y `app. ETHOD()` funciona, donde `METHOD` es el método HTTP de la petición que la función middleware maneja (como GET, PUT o POST) en minúsculas. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -Este ejemplo muestra una función de middleware sin ruta de montaje. La función se ejecuta cada vez que la aplicación recibe una solicitud. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -Este ejemplo muestra una función middleware montada en la ruta `/user/:id`. La función se ejecuta para cualquier tipo de petición -HTTP en la ruta `/user/:id`. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Manejadores de rutas + Este ejemplo muestra una ruta y su función manejadora (middleware system). La función maneja peticiones GET a la ruta `/user/:id`. ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -He aquí un ejemplo de carga de una serie de funciones de middleware en un punto de montaje, con una ruta de montaje. -Ilustra un substack de middleware que imprime la información de la petición para cualquier tipo de petición HTTP a la ruta `/user/:id`. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Los manejadores de rutas le permiten definir múltiples rutas para una ruta. El siguiente ejemplo define dos rutas para peticiones GET a la ruta `/user/:id`. La segunda ruta no causará ningún problema, pero nunca se llamará porque la primera ruta termina el ciclo de solicitud de respuesta. +### Multiple route handlers -Este ejemplo muestra un substack de middleware que maneja peticiones GET a la ruta `/user/:id`. +Los manejadores de rutas le permiten definir múltiples rutas para una ruta. El siguiente ejemplo define dos rutas para peticiones GET a la ruta `/user/:id`. La segunda ruta no causará ningún problema, pero nunca se llamará porque la primera ruta termina el ciclo de solicitud de respuesta. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -Para omitir el resto de las funciones de middleware desde una pila de middleware de router, llame a `next('ruta')` para pasar el control a la siguiente ruta. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ Para omitir el resto de las funciones de middleware desde una pila de middleware -Este ejemplo muestra un substack de middleware que maneja peticiones GET a la ruta `/user/:id`. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Middleware también puede ser declarado en una matriz para reusabilidad. +### Reusable middleware arrays -Este ejemplo muestra una matriz con un substack de middleware que maneja peticiones GET en la ruta `/user/:id` +Middleware functions can also be grouped into arrays for better reusability. Este ejemplo muestra una matriz con un substack de middleware que maneja peticiones GET en la ruta `/user/:id` ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,14 +280,14 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Middleware de nivel remoto -El middleware Router-level funciona de la misma manera que el middleware a nivel de aplicación, excepto que está vinculado a una instancia de `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); @@ -319,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -369,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -419,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -440,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -Para omitir el resto de las funciones de middleware del enrutador, llama a `next('router')` -para pasar el control de vuelta fuera de la instancia del enrutador. +### Skipping out of a router + +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. -Este ejemplo muestra un substack de middleware que maneja peticiones GET a la ruta `/user/:id`. +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -512,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Middleware de manejo de errores - - -Middleware manejado por errores siempre toma _four_ argumentos. Debe proporcionar cuatro argumentos para -identificarlo como una función de middleware que maneja errores. Incluso si no necesitas usar el objeto `next` -, debes especificarlo para mantener la firma. De lo contrario, el objeto `siguiente` será -interpretado como middleware regular y fallará al manejar errores. - - - Define las funciones de middleware de la misma manera que otras funciones de middleware, excepto con cuatro argumentos en lugar de tres, específicamente con la firma `(err, req, res, next)`: ```js @@ -539,18 +543,30 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Para más detalles sobre el middleware de manejo de errores, vea: [Gestión de errores](/guide/error-handling). + -## Middleware incorporado +Middleware manejado por errores siempre toma _four_ argumentos. Debe proporcionar cuatro argumentos para +identificarlo como una función de middleware que maneja errores. Incluso si no necesitas usar el objeto `next` +, debes especificarlo para mantener la firma. De lo contrario, el objeto `siguiente` será +interpretado como middleware regular y fallará al manejar errores. + + + + -A partir de la versión 4.x, Express ya no depende de [Connect](https://github.com/senchalabs/connect). Las funciones -del middleware que anteriormente estaban incluidas con Express están ahora en módulos separados; vea [la lista de funciones de middleware](https://github.com/senchalabs/connect#middleware). +For more information, see the [Error handling](/guide/error-handling) guide. + + + +## Middleware incorporado Express tiene las siguientes funciones de middleware incorporadas: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. -- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTA: Disponible con Express 4.16.0+** -- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTA: Disponible con Express 4.16.0+** +- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. +- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. ## Middleware de terceros @@ -591,4 +607,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Para una lista parcial de funciones de middleware de terceros que se utilizan comúnmente con Express, vea: [Middleware de terceros](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/es/5x/guide/using-template-engines.mdx b/src/content/docs/es/5x/guide/using-template-engines.mdx index 343047c631..aef88abea2 100644 --- a/src/content/docs/es/5x/guide/using-template-engines.mdx +++ b/src/content/docs/es/5x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Utilizando motores de plantillas con Express -description: Descubra cómo integrar y utilizar motores de plantillas como Pug, Handlebars y EJS con Express.js para renderizar páginas HTML dinámicas eficientemente. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ Un _template engine_ le permite usar plantillas estáticas en su aplicación. En en un archivo de plantilla con valores reales. y transforma la plantilla en un archivo HTML enviado al cliente. Este enfoque facilita el diseño de una página HTML. -El [generador de aplicaciones Express](/starter/generator) utiliza [Pug](https://pugjs.org/api/getting-started.html) como predeterminado, pero también soporta [Handlebars](https://www.npmjs.com/package/handlebars), y [EJS](https://www.npmjs.com/package/ejs), entre otros. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `vistas`, el directorio donde están ubicados los archivos de plantilla. Ej: `app.set('vistas', './views')`. Esto por defecto es el directorio `views` en el directorio raíz de la aplicación. - `ver engine`, el motor de plantillas a usar. Por ejemplo, para usar el motor de plantillas Pug: `app.set('view engine', 'pug')`. -A continuación, instale el correspondiente paquete npm del motor de plantillas; por ejemplo para instalar Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ que `res.render()` llama para renderizar el código de plantilla. Algunos motores de plantillas no siguen esta convención. La biblioteca [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) sigue esta convención mapeando todos los motores de plantillas populares de Node.js, y por lo tanto funciona perfectamente dentro de Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/es/5x/guide/writing-middleware.mdx b/src/content/docs/es/5x/guide/writing-middleware.mdx index fc3be548b3..369cdb7fb8 100644 --- a/src/content/docs/es/5x/guide/writing-middleware.mdx +++ b/src/content/docs/es/5x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Aprenda cómo escribir funciones personalizadas de middleware para --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Además, la función de callback de la ruta raíz utiliza la propiedad que la función middleware añade a `req` (el objeto de la solicitud). La aplicación ahora utiliza la función de middleware `requestTime`. @@ -170,8 +171,8 @@ La función Middleware `myLogger` simplemente imprime un mensaje, luego pasa la ### Tiempo de solicitud de la función Middleware -A continuación, crearemos una función de middleware llamada "requestTime" y agregaremos una propiedad llamada `requestTime` -al objeto de la solicitud. +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -391,9 +392,13 @@ que no sea de manejo de enrutamiento y middleware restante. -Debido a que tiene acceso al objeto de solicitud, el objeto de respuesta, la siguiente función de middleware en la pila, y el nodo entero. s API, las posibilidades con funciones middleware son infinitas. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Para más información sobre middleware exprés, vea: [Usando middleware exprés](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Middleware configurable diff --git a/src/content/docs/es/5x/starter/basic-routing.mdx b/src/content/docs/es/5x/starter/basic-routing.mdx index 912969eebe..ca569b5a6d 100644 --- a/src/content/docs/es/5x/starter/basic-routing.mdx +++ b/src/content/docs/es/5x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Aprenda los fundamentos de la enrutamiento en aplicaciones Express. --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Enrutamiento_ se refiere a determinar cómo responde una aplicación a una solicitud de cliente a un punto final en particular, que es una URI (o ruta) y un método específico de petición HTTP (GET, POST, etc.). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -Para más detalles sobre enrutamiento, vea la [guía de enrutamiento](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/es/5x/starter/faq.mdx b/src/content/docs/es/5x/starter/faq.mdx index cf1570c309..9d5d0f31af 100644 --- a/src/content/docs/es/5x/starter/faq.mdx +++ b/src/content/docs/es/5x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Encuentre respuestas a preguntas frecuentes sobre Express.js, incluyendo temas sobre estructura de aplicaciones, modelos, autenticación, motores de plantillas, manejo de errores, y más. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## ¿Cómo debo estructurar mi aplicación? No hay una respuesta definitiva a esta pregunta. La respuesta depende @@ -42,7 +44,11 @@ Para normalizar las interfaces del motor de plantillas y la caché, consulte el [consolidate.js](https://github.com/visionmedia/consolidate.js) para obtener soporte. Los motores de plantillas no listados pueden seguir soportando la firma Express. -Para obtener más información, consulte [Usar motores de plantilla con Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## ¿Cómo puedo manejar las respuestas 404? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Para más información, vea [Gestión de errores](/en/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## ¿Cómo renderizo HTML plano? diff --git a/src/content/docs/es/5x/starter/installing.mdx b/src/content/docs/es/5x/starter/installing.mdx index 39f7f2a879..dbbcd16003 100644 --- a/src/content/docs/es/5x/starter/installing.mdx +++ b/src/content/docs/es/5x/starter/installing.mdx @@ -70,7 +70,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/es/5x/starter/static-files.mdx b/src/content/docs/es/5x/starter/static-files.mdx index 2cf6f3c20f..02619b37a3 100644 --- a/src/content/docs/es/5x/starter/static-files.mdx +++ b/src/content/docs/es/5x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Describa cómo servir archivos estáticos como imágenes, CSS y Jav --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Para servir archivos estáticos como imágenes, archivos CSS, y archivos JavaScript, utiliza la función middleware integrada `express.static` en Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + Para más detalles sobre la función `serve-static` y sus opciones, vea [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/fr/4x/guide/debugging.mdx b/src/content/docs/fr/4x/guide/debugging.mdx index 634068204c..f4b1a0522c 100644 --- a/src/content/docs/fr/4x/guide/debugging.mdx +++ b/src/content/docs/fr/4x/guide/debugging.mdx @@ -4,6 +4,7 @@ description: Apprenez comment activer et utiliser les journaux de débogage dans --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; Pour voir tous les journaux internes utilisés dans Express, définissez la variable d'environnement `DEBUG` à `express:*` lors du lancement de votre application. @@ -86,22 +87,119 @@ Lorsqu'une demande est faite à l'application, vous verrez les journaux spécifi Pour voir les logs uniquement à partir de l'implémentation du routeur, définissez la valeur de `DEBUG` à `express:router`. De même, pour ne voir que les logs de l'implémentation de l'application, définissez la valeur de `DEBUG` à `express:application`, et ainsi de suite. -## Applications générées par `express` +## Using `debug` in your own code -Une application générée par la commande `express` utilise le module `debug` et son espace de noms de débogage est limité au nom de l'application. +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: -Par exemple, si vous avez généré l'application avec `$ express sample-app`, vous pouvez activer les instructions de débogage avec la commande suivante : + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; + +const debug = debugModule('myapp:server'); +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` Vous pouvez spécifier plus d'un espace de noms de débogage en assignant une liste de noms séparés par des virgules : ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,express:router node index.js +``` + +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*" } +} ``` +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Options avancées Lors de l'exécution de Node.js, vous pouvez définir quelques variables d'environnement qui changeront le comportement du journal de débogage : diff --git a/src/content/docs/fr/4x/guide/error-handling.mdx b/src/content/docs/fr/4x/guide/error-handling.mdx index 353e790948..9160e7bc1d 100644 --- a/src/content/docs/fr/4x/guide/error-handling.mdx +++ b/src/content/docs/fr/4x/guide/error-handling.mdx @@ -62,14 +62,16 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -À partir de Express 5, les gestionnaires de route et les middleware qui retournent une Promise -appelleront automatiquement `next(value)` quand ils rejettent ou lancent une erreur. -Par exemple : +Errors from rejected promises are not passed to `next` automatically, and this includes `async` functions: if an `async` route handler throws or awaits a rejected promise, the rejection is unhandled, which crashes the process on current Node.js versions. You must catch the error yourself and pass it to Express: ```js app.get('/user/:id', async (req, res, next) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` @@ -77,14 +79,22 @@ app.get('/user/:id', async (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` -Si `getUserById` lance une erreur ou un rejet, `next` sera appelé avec soit -l'erreur émise ou la valeur rejetée. Si aucune valeur rejetée n'est fournie, `next` -sera appelée avec un objet Error par défaut fourni par le routeur Express. + + +Consider [updating to Express 5](/guide/migrating-5), where route handlers and middleware that +return a Promise call `next(value)` automatically when they reject or throw an error, making the +`try...catch` above unnecessary. + + If you pass anything to the `next()` function (except the string `'route'`), Express regards the current request as being an error and will skip any @@ -180,9 +190,7 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Puisque les promesses attrapent automatiquement à la fois les erreurs synchrones et les promesses rejetées, -vous pouvez simplement fournir `next` car le gestionnaire de capture final et Express attrapera des erreurs, -parce que le gestionnaire de capture est donné l'erreur comme premier argument. +If a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, passing `next` as the handler is enough: `.catch` calls it with the error as its first argument, which is exactly the argument `next` expects, so the error reaches Express. Vous pouvez également utiliser une chaîne de gestionnaires pour vous fier à l'erreur synchrone attrapant, en réduisant le code asynchrone à quelque chose de trivial. Par exemple : @@ -219,8 +227,8 @@ app.get('/', [ ]); ``` -L'exemple ci-dessus a quelques déclarations triviales de l'appel `readFile` -. Si `readFile` cause une erreur, alors il passe l'erreur à Express, sinon vous +The above example contains a couple of trivial statements following the `readFile` +call. Si `readFile` cause une erreur, alors il passe l'erreur à Express, sinon vous revenez rapidement au monde de la gestion des erreurs synchrones dans le prochain gestionnaire de la chaîne. Ensuite, l'exemple ci-dessus tente de traiter les données. Si cela échoue, alors le gestionnaire d'erreurs synchrone l'attrapera. Si vous aviez fait ce traitement à l'intérieur de @@ -424,7 +432,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Aussi dans cet exemple, `clientErrorHandler` est défini comme suit ; dans ce cas, l'erreur est explicitement passée au suivant. -Notez que lorsque _not_ appelez "next" dans une fonction de gestion des erreurs, vous êtes responsable de l'écriture (et de la fin) de la réponse. Sinon, ces demandes seront « bloquées » et ne seront pas admissibles au ramassage des déchets. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Sinon, ces demandes seront « bloquées » et ne seront pas admissibles au ramassage des déchets. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/fr/4x/guide/overriding-express-api.mdx b/src/content/docs/fr/4x/guide/overriding-express-api.mdx index 3a4e12e346..3b1e7bb173 100644 --- a/src/content/docs/fr/4x/guide/overriding-express-api.mdx +++ b/src/content/docs/fr/4x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -L'API Express se compose de différentes méthodes et propriétés sur les objets de requête et de réponse. Celles-ci sont héritées du prototype. Il y a deux points d'extension pour l'API Express : +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. Celles-ci sont héritées du prototype. Il y a deux points d'extension pour l'API Express : 1. Les prototypes globaux à `express.request` et `express.response`. 2. Prototypes spécifiques à l'application à `app.request` et `app.response`. diff --git a/src/content/docs/fr/4x/guide/routing.mdx b/src/content/docs/fr/4x/guide/routing.mdx index 0390c32318..1d718b7379 100644 --- a/src/content/docs/fr/4x/guide/routing.mdx +++ b/src/content/docs/fr/4x/guide/routing.mdx @@ -13,7 +13,7 @@ par exemple, `app. et()` pour gérer les requêtes GET et `app.post` pour gérer see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. En d'autres termes, l'application "écoute" les requêtes qui correspondent à la(les) route(s) spécifiée(s) et à la(les) méthode(s), et quand il détecte une correspondance, il appelle la fonction de rappel spécifiée. +En d'autres termes, l'application "écoute" les requêtes qui correspondent à la(les) route(s) spécifiée(s) et à la(les) méthode(s), et quand il détecte une correspondance, il appelle la fonction de rappel spécifiée. En d'autres termes, l'application "écoute" les requêtes qui correspondent à la(les) route(s) spécifiée(s) et à la(les) méthode(s), et quand il détecte une correspondance, il appelle la fonction de rappel spécifiée. En fait, les méthodes de routage peuvent avoir plus d'une fonction de rappel en tant qu'arguments. Avec plusieurs fonctions de rappel, il est important de fournir `next` comme argument à la fonction de callback puis appeler `next()` dans le corps de la fonction pour distribuer le contrôle @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express supporte les méthodes qui correspondent à toutes les méthodes de requête HTTP : `get`, `post`, et ainsi de suite. For a full list, see [app.METHOD](/api/application#appmethod). -Il y a une méthode de routage spéciale, `app.all()`, utilisée pour charger les fonctions du middleware à un chemin pour _toutes_ les méthodes de requête HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +Il y a une méthode de routage spéciale, `app.all()`, utilisée pour charger les fonctions du middleware à un chemin pour _toutes_ les méthodes de requête HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Chemins de la route -Les chemins de la route, en combinaison avec une méthode de requête, définissent les points de terminaison à partir desquels les requêtes peuvent être faites. Les chemins de route peuvent être des chaînes, des chaînes de caractères ou des expressions régulières. +Les chemins de la route, en combinaison avec une méthode de requête, définissent les points de terminaison à partir desquels les requêtes peuvent être faites. Les chemins de route peuvent être des chaînes, des chaînes de caractères ou des expressions régulières. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -235,6 +235,26 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => { }); ``` +A wildcard (`*`) on its own matches anything at its position, including entire subpaths. For example, this route path will match `/file/style.css` as well as `/file/javascripts/jquery.js`. Wildcards are unnamed, so the matched value is available as `req.params[0]` instead of a named parameter. + +```js +app.get('/file/*', (req, res) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/file/*', (req: Request, res: Response) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + ### Chemins de route basés sur des expressions régulières @@ -348,6 +368,14 @@ avec un antislash supplémentaire, par exemple `\d+`. The [`*`](https://github.com/expressjs/express/issues/2495) character in regular expressions is not interpreted in the usual way. Comme solution de contournement, utilisez `{0,}` au lieu de `*`. +Unlike named route parameters, wildcard (`*`) matches in [string patterns](#route-paths-based-on-string-patterns) and capture groups in regular expressions are unnamed: their values are available by position, as `req.params[0]`, `req.params[1]`, and so on. + +``` +Route path: /file/*/size/* +Request URL: http://localhost:3000/file/javascripts/jquery.js/size/large +req.params: { "0": "javascripts/jquery.js", "1": "large" } +``` + ## Gestionnaires de routes Vous pouvez fournir plusieurs fonctions de rappel qui se comportent comme [middleware](/guide/using-middleware) pour traiter une requête. La seule exception est que ces callbacks peuvent appeler `next('route')` pour contourner les rappels de route restants. Vous pouvez utiliser ce mécanisme pour imposer des conditions préalables sur une route, passent ensuite le contrôle aux routes suivantes s'il n'y a pas de raison de poursuivre l'itinéraire courant. @@ -387,7 +415,7 @@ Dans cet exemple : Les gestionnaires de routes peuvent être sous la forme d'une fonction, d'un tableau de fonctions, ou de combinaisons des deux, comme indiqué dans les exemples suivants. -Une seule fonction de rappel peut gérer une route. Par exemple : +Une combinaison de fonctions indépendantes et de tableaux de fonctions peut gérer une route. Par exemple : ```js app.get('/example/a', (req, res) => { @@ -527,7 +555,7 @@ app.get( ## Méthodes de réponse -Les méthodes de l'objet de réponse (`res`) dans la table suivante peuvent envoyer une réponse au client et terminer le cycle de réponse de la requête. Si aucune de ces méthodes n'est appelée à partir d'un gestionnaire d'itinéraire, la requête du client sera suspendue. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. Si aucune de ces méthodes n'est appelée à partir d'un gestionnaire d'itinéraire, la requête du client sera suspendue.| Method | Description | Méthode | Libellé | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------- | @@ -544,7 +572,7 @@ Les méthodes de l'objet de réponse (`res`) dans la table suivante peuvent envo ## app.route() Vous pouvez créer des gestionnaires de routes chaînables pour un chemin en utilisant `app.route()`. -Parce que le chemin est spécifié à un seul endroit, la création de routes modulaires est utile, tout comme la réduction de la redondance et des fautes de frappe. Pour plus d'informations sur les routes, voir : [Documentation de Router()](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router). Voici un exemple de gestionnaires de routes enchaînés qui sont définis en utilisant `app.route()`. @@ -580,7 +608,7 @@ app ## Routeur -Utilisez la classe `express.Router` pour créer des gestionnaires de route modulaires et montables. Une instance `Router` est un système complet de middleware et de routage ; pour cette raison, elle est souvent appelée "mini-app". +Utilisez la classe `express.Router` pour créer des gestionnaires de route modulaires et montables. Une instance `Router` est un système complet de middleware et de routage ; pour cette raison, elle est souvent appelée "mini-app".The following example creates a router as a module, loads a middlew L'exemple suivant crée un routeur en tant que module, charge une fonction middleware dedans, définit quelques routes, et monte le module routeur sur un chemin dans l'application principale. @@ -677,7 +705,7 @@ app.use('/birds', birds); L'application sera maintenant en mesure de traiter les demandes vers `/birds` et `/birds/about`, ainsi que d'appeler la fonction middleware `timeLog` qui est spécifique à la route. -Mais si la route parente `/birds` a des paramètres de chemin, elle ne sera pas accessible par défaut à partir des sous-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +Mais si la route parente `/birds` a des paramètres de chemin, elle ne sera pas accessible par défaut à partir des sous-routes. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter). ```js const router = express.Router({ mergeParams: true }); diff --git a/src/content/docs/fr/4x/guide/using-middleware.mdx b/src/content/docs/fr/4x/guide/using-middleware.mdx index 671526338f..d78082c62d 100644 --- a/src/content/docs/fr/4x/guide/using-middleware.mdx +++ b/src/content/docs/fr/4x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Apprenez à utiliser les middleware dans les applications Express.j import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express est un framework web de routage et de middleware qui possède des fonctionnalités minimales : Une application Express est essentiellement une série d'appels de fonctions de middleware. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -Les fonctions _Middleware_ sont des fonctions qui ont accès à l'objet [request object](/api#req) (`req`), l'objet [réponse](/api#res) (`res`), et la prochaine fonction du middleware dans le cycle de réponse de l'application. La prochaine fonction du middleware est généralement dénotée par une variable nommée `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Les fonctions Middleware peuvent effectuer les tâches suivantes : - Exécuter n'importe quel code. -- Effectuez des modifications à la requête et aux objets de réponse. +- Modify the request and response objects. - Termine le cycle de réponse de la requête. -- Appeler la prochaine fonction du middleware dans la pile. +- Pass control to the next middleware function. -Si la fonction middleware actuelle ne met pas fin au cycle de réponse de requête, elle doit appeler `next()` pour passer le contrôle à la prochaine fonction du middleware. Sinon, la demande sera laissée en suspens. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Sinon, la demande sera laissée en suspens. Une application Express peut utiliser les types de middleware suivants : @@ -27,14 +32,15 @@ Une application Express peut utiliser les types de middleware suivants : - (#middleware.built-in) - [middleware de tierce partie](#middleware.third-party) -Vous pouvez charger le middleware au niveau de l'application et du routeur avec un chemin de montage optionnel. -Vous pouvez également charger une série de fonctions middleware ensemble, ce qui crée une sous-pile du système middleware à un point de montage. +Vous pouvez charger le middleware au niveau de l'application et du routeur avec un chemin de montage optionnel. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Outil d'interface de l'application -Lier le middleware au niveau de l'application à une instance de l'objet [app object](/api#app) en utilisant `app.use()` et `app. Les fonctions ETHOD()`, où `METHOD` est la méthode HTTP de la requête que la fonction middleware gère (comme GET, PUT ou POST) en minuscule. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -Cet exemple montre une fonction middleware sans chemin de montage. La fonction est exécutée chaque fois que l'application reçoit une requête. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -Cet exemple montre une fonction middleware montée sur le chemin `/user/:id`. La fonction est exécutée pour n'importe quel type de requête HTTP -sur le chemin `/user/:id`. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Gestionnaires de routes + Cet exemple montre une route et sa fonction de gestion (système middleware). La fonction gère les requêtes GET vers le chemin `/user/:id`. ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Voici un exemple de chargement d'une série de fonctions middleware à un point de montage, avec un chemin de montage. -Il illustre une sous-pile middleware qui affiche les informations de requête pour tout type de requête HTTP vers le chemin `/user/:id`. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Les gestionnaires de routes vous permettent de définir plusieurs routes pour un chemin. L'exemple ci-dessous définit deux routes pour les requêtes GET vers le chemin `/user/:id`. La deuxième route ne posera aucun problème, mais elle ne sera jamais appelée parce que le premier parcours termine le cycle de réponse de la requête. +### Multiple route handlers -Cet exemple montre une sous-pile middleware qui gère les requêtes GET vers le chemin `/user/:id`. +Les gestionnaires de routes vous permettent de définir plusieurs routes pour un chemin. L'exemple ci-dessous définit deux routes pour les requêtes GET vers le chemin `/user/:id`. La deuxième route ne posera aucun problème, mais elle ne sera jamais appelée parce que le premier parcours termine le cycle de réponse de la requête. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -Pour sauter le reste des fonctions du middleware à partir d'une pile de middleware du routeur, appelez `next('route')` pour passer le contrôle à la route suivante. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ Pour sauter le reste des fonctions du middleware à partir d'une pile de middlew -Cet exemple montre une sous-pile middleware qui gère les requêtes GET vers le chemin `/user/:id`. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Les Middleware peuvent également être déclarés dans un tableau pour être réutilisables. +### Reusable middleware arrays -Cet exemple montre un tableau avec une sous-pile middleware qui gère les requêtes GET vers le chemin `/user/:id` +Middleware functions can also be grouped into arrays for better reusability. Cet exemple montre un tableau avec une sous-pile middleware qui gère les requêtes GET vers le chemin `/user/:id` ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,19 +280,25 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## middleware au niveau du routeur -Le middleware au niveau du routeur fonctionne de la même manière que le middleware au niveau de l'application, sauf qu'il est lié à une instance de `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); ``` +```ts +import express from 'express'; + +const router = express.Router(); +``` + Charger le middleware au niveau du routeur en utilisant les fonctions `router.use()` et `router.METHOD()`. L'exemple suivant réplique le système middleware qui est affiché ci-dessus pour le middleware au niveau de l'application, en utilisant le middleware au niveau du routeur: @@ -313,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -363,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -413,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -434,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -Pour sauter le reste des fonctions du middleware du routeur, appelez `next('router')` -pour passer le contrôle hors de l'instance du routeur. +### Skipping out of a router -Cet exemple montre une sous-pile middleware qui gère les requêtes GET vers le chemin `/user/:id`. +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. + +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -506,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Gestion des erreurs du middleware - - -La gestion d'erreurs du middleware prend toujours _four_ arguments. Vous devez fournir quatre arguments à -l'identifier comme une fonction de gestion des erreurs du middleware. Même si vous n'avez pas besoin d'utiliser l'objet `next` -, vous devez le spécifier pour maintenir la signature. Sinon, l'objet `next` sera -interprété comme un middleware normal et ne gérera pas les erreurs. - - - Définissez les fonctions du middleware de la même manière que les autres fonctions du middleware, sauf avec quatre arguments au lieu de trois, spécifiquement avec la signature `(err, req, res, next)`: ```js @@ -533,7 +543,20 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Pour plus de détails sur la gestion des erreurs du middleware, voir : [Gestion des erreurs](/guide/error-handling). + + +La gestion d'erreurs du middleware prend toujours _four_ arguments. Vous devez fournir quatre arguments à +l'identifier comme une fonction de gestion des erreurs du middleware. Même si vous n'avez pas besoin d'utiliser l'objet `next` +, vous devez le spécifier pour maintenir la signature. Sinon, l'objet `next` sera +interprété comme un middleware normal et ne gérera pas les erreurs. + + + + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## middleware intégré @@ -544,6 +567,8 @@ Express a les fonctions internes suivantes : - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. - [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTE : Disponible avec Express 4.16.0+** +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. **NOTE: Available with Express 4.17.0+** +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. **NOTE: Available with Express 4.17.0+** - [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTE : Disponible avec Express 4.16.0+** ## middleware de tierce partie @@ -585,4 +610,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Pour une liste partielle des fonctions middleware tierces qui sont couramment utilisées avec Express, voir : [middleware de tierce] (../resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/fr/4x/guide/using-template-engines.mdx b/src/content/docs/fr/4x/guide/using-template-engines.mdx index 6e8a650917..2d3d4be633 100644 --- a/src/content/docs/fr/4x/guide/using-template-engines.mdx +++ b/src/content/docs/fr/4x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Utiliser les moteurs de gabarits avec Express -description: Découvrez comment intégrer et utiliser des moteurs de gabarits tels que Pug, Handlebars et EJS avec Express.js pour rendre les pages HTML dynamiques efficacement. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ Un _moteur de modèle_ vous permet d'utiliser des fichiers de modèles statiques dans un fichier de gabarit par des valeurs réelles, et transforme le modèle en un fichier HTML envoyé au client. Cette approche facilite la conception d'une page HTML. -Le [générateur d'application Express](/starter/generator) utilise [Pug](https://pugjs.org/api/getting-started.html) par défaut, mais il supporte aussi [Handlebars](https://www.npmjs.com/package/handlebars), et [EJS](https://www.npmjs.com/package/ejs), entre autres. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, le répertoire où se trouvent les fichiers de modèle. Ex. : `app.set('vues', './views')`. Par défaut, le répertoire `views` se trouve à la racine de l'application. - `voir le moteur`, le moteur de gabarit à utiliser. Par exemple, pour utiliser le moteur de gabarit Pug : `app.set('moteur de vue', 'pug')`. -Ensuite, installez le paquet npm correspondant au moteur de gabarits ; par exemple pour installer Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ qui `res.render()` appelle pour rendre le code du gabarit. Certains moteurs de gabarits ne suivent pas cette convention. La bibliothèque [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) suit cette convention en mappant tous les moteurs de gabarits populaires Node.js, et fonctionne donc parfaitement dans Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/fr/4x/guide/writing-middleware.mdx b/src/content/docs/fr/4x/guide/writing-middleware.mdx index 4794d87801..e1a489f638 100644 --- a/src/content/docs/fr/4x/guide/writing-middleware.mdx +++ b/src/content/docs/fr/4x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Apprenez à écrire des fonctions personnalisées de middleware pou --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Aussi, la fonction callback de la route du chemin racine utilise la propriété que la fonction middleware ajoute à `req` (l'objet de requête). L'application utilise maintenant la fonction middleware `requestTime`. @@ -199,8 +200,8 @@ La fonction du middleware `myLogger` affiche simplement un message, passe ensuit ### Middleware fonction requestTime -Ensuite, nous allons créer une fonction middleware appelée "requestTime" et ajouter une propriété appelée `requestTime` -à l'objet requête. +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -420,9 +421,13 @@ qui ne gère pas les autres fonctions de routage. -Parce que vous avez accès à l'objet requête, à l'objet de réponse, à la prochaine fonction du middleware dans la pile, et à l'ensemble du nœud. s API, les possibilités avec les fonctions du middleware sont infinies. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Pour plus d'informations sur le middleware Express, voir : [Utiliser un middleware Express](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Logiciel middleware configurable diff --git a/src/content/docs/fr/4x/starter/basic-routing.mdx b/src/content/docs/fr/4x/starter/basic-routing.mdx index 52a6d1de2f..2b4a3ea620 100644 --- a/src/content/docs/fr/4x/starter/basic-routing.mdx +++ b/src/content/docs/fr/4x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Apprenez les fondamentaux du routage dans les applications Express. --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ désigne la façon dont une application répond à une requête client à un point de terminaison particulier, qui est une URI (ou un chemin) et une méthode spécifique de requête HTTP (GET, POST, etc.). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -Pour plus de détails sur le routage, consultez le [guide de routage](/en/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/fr/4x/starter/faq.mdx b/src/content/docs/fr/4x/starter/faq.mdx index 3d2f026b51..6ac2c9501a 100644 --- a/src/content/docs/fr/4x/starter/faq.mdx +++ b/src/content/docs/fr/4x/starter/faq.mdx @@ -3,6 +3,8 @@ title: Foire Aux Questions description: Retrouvez les réponses aux questions les plus fréquemment posées sur Express.js, y compris les sujets sur la structure de l'application, les modèles, l'authentification, les moteurs de gabarit, la gestion des erreurs, et plus encore. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## Comment structurer ma candidature ? Il n'y a pas de réponse définitive à cette question. La réponse dépend @@ -42,7 +44,11 @@ Pour normaliser les interfaces du moteur de gabarits et la mise en cache, consul [consolidate.js](https://github.com/visionmedia/consolidate.js) pour plus de support. Les moteurs de gabarits non listés peuvent toujours supporter la signature Express. -Pour plus d'informations, voir [Utilisation de moteurs de gabarits avec Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## Comment gérer 404 réponses? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Pour plus d'informations, voir [Gestion des erreurs](/en/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Comment rendre le HTML simple ? diff --git a/src/content/docs/fr/4x/starter/installing.mdx b/src/content/docs/fr/4x/starter/installing.mdx index e2b82d91e9..26ea3da08d 100644 --- a/src/content/docs/fr/4x/starter/installing.mdx +++ b/src/content/docs/fr/4x/starter/installing.mdx @@ -79,7 +79,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/fr/4x/starter/static-files.mdx b/src/content/docs/fr/4x/starter/static-files.mdx index b1fffa2e01..0a7402e0c7 100644 --- a/src/content/docs/fr/4x/starter/static-files.mdx +++ b/src/content/docs/fr/4x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Comprendre comment servir les fichiers statiques comme les images, --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Pour servir des fichiers statiques tels que des images, des fichiers CSS et des fichiers JavaScript, utilisez la fonction middleware intégrée `express.static` dans Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + Pour plus de détails sur la fonction `serve-static` et ses options, voir [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/fr/5x/guide/debugging.mdx b/src/content/docs/fr/5x/guide/debugging.mdx index 634068204c..c007950171 100644 --- a/src/content/docs/fr/5x/guide/debugging.mdx +++ b/src/content/docs/fr/5x/guide/debugging.mdx @@ -4,104 +4,218 @@ description: Apprenez comment activer et utiliser les journaux de débogage dans --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -Pour voir tous les journaux internes utilisés dans Express, définissez la variable d'environnement `DEBUG` à -`express:*` lors du lancement de votre application. +To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*,router,router:*` when launching your app. Routing is handled by the separate [router](https://github.com/pillarjs/router) package, so its logs live under the `router` namespace and are not included in `express:*`. ```bash -$ DEBUG=express:* node index.js +$ DEBUG=express:*,router,router:* node index.js ``` Sous Windows, utilisez la commande correspondante. ```bash -> $env:DEBUG = "express:*"; node index.js +> $env:DEBUG = "express:*,router,router:*"; node index.js ``` -L'exécution de cette commande sur l'application par défaut générée par le [générateur express](/starter/generator) affiche la sortie suivante: +Running this command on a small app with a JSON body parser and a mounted router prints the following output: + +```cjs title="index.cjs" +const express = require('express'); + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` + +```mjs title="index.mjs" +import express from 'express'; + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` ```bash -$ DEBUG=express:* node ./bin/www - express:router:route new / +0ms - express:router:layer new / +1ms - express:router:route get / +1ms - express:router:layer new / +0ms - express:router:route new / +1ms - express:router:layer new / +0ms - express:router:route get / +0ms - express:router:layer new / +0ms - express:application compile etag weak +1ms - express:application compile query parser extended +0ms - express:application compile trust proxy false +0ms - express:application booting in development mode +1ms - express:router use / query +0ms - express:router:layer new / +0ms - express:router use / expressInit +0ms - express:router:layer new / +0ms - express:router use / favicon +1ms - express:router:layer new / +0ms - express:router use / logger +0ms - express:router:layer new / +0ms - express:router use / jsonParser +0ms - express:router:layer new / +1ms - express:router use / urlencodedParser +0ms - express:router:layer new / +0ms - express:router use / cookieParser +0ms - express:router:layer new / +0ms - express:router use / stylus +90ms - express:router:layer new / +0ms - express:router use / serveStatic +0ms - express:router:layer new / +0ms - express:router use / router +0ms - express:router:layer new / +1ms - express:router use /users router +0ms - express:router:layer new /users +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms +$ DEBUG=express:*,router,router:* node index.js + express:application set "x-powered-by" to true +0ms + express:application set "etag" to 'weak' +3ms + express:application set "etag fn" to [Function: generateETag] +0ms + express:application set "env" to 'development' +1ms + express:application set "query parser" to 'simple' +0ms + express:application set "query parser fn" to [Function: parse] +0ms + express:application set "subdomain offset" to 2 +1ms + express:application set "trust proxy" to false +0ms + express:application set "trust proxy fn" to [Function: trustNone] +1ms + express:application booting in development mode +0ms + express:application set "view" to [Function: View] +0ms + express:application set "views" to '/projects/example/views' +1ms + express:application set "jsonp callback name" to 'callback' +0ms + router use '/' jsonParser +0ms + router:layer new '/' +0ms + router:route new '/' +0ms + router:layer new '/' +3ms + router:route get / +0ms + router:layer new '/' +1ms + router use '/users' router +4ms + router:layer new '/users' +0ms + router:route new '/' +1ms + router:layer new '/' +0ms + router:route get / +1ms + router:layer new '/' +1ms ``` Lorsqu'une demande est faite à l'application, vous verrez les journaux spécifiés dans le code Express: ```bash - express:router dispatching GET / +4h - express:router query : / +2ms - express:router expressInit : / +0ms - express:router favicon : / +0ms - express:router logger : / +1ms - express:router jsonParser : / +0ms - express:router urlencodedParser : / +1ms - express:router cookieParser : / +0ms - express:router stylus : / +0ms - express:router serveStatic : / +2ms - express:router router : / +2ms - express:router dispatching GET / +1ms - express:view lookup "index.pug" +338ms - express:view stat "/projects/example/views/index.pug" +0ms - express:view render "/projects/example/views/index.pug" +1ms + router dispatching GET /users +712ms + router jsonParser : /users +1ms + router trim prefix (/users) from url /users +2ms + router router /users : /users +0ms + router dispatching GET / +0ms +``` + +To see the logs only from the router implementation, set the value of `DEBUG` to `router,router:*`. De même, pour ne voir que les logs de l'implémentation de l'application, définissez la valeur de `DEBUG` à `express:application`, et ainsi de suite. + +## Using `debug` in your own code + +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: + + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); ``` -Pour voir les logs uniquement à partir de l'implémentation du routeur, définissez la valeur de `DEBUG` à `express:router`. De même, pour ne voir que les logs de l'implémentation de l'application, définissez la valeur de `DEBUG` à `express:application`, et ainsi de suite. +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; -## Applications générées par `express` +const debug = debugModule('myapp:server'); +const app = express(); -Une application générée par la commande `express` utilise le module `debug` et son espace de noms de débogage est limité au nom de l'application. +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); -Par exemple, si vous avez généré l'application avec `$ express sample-app`, vous pouvez activer les instructions de débogage avec la commande suivante : +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` Vous pouvez spécifier plus d'un espace de noms de débogage en assignant une liste de noms séparés par des virgules : ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,router node index.js ``` +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*,router,router:*" } +} +``` + +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Options avancées Lors de l'exécution de Node.js, vous pouvez définir quelques variables d'environnement qui changeront le comportement du journal de débogage : diff --git a/src/content/docs/fr/5x/guide/error-handling.mdx b/src/content/docs/fr/5x/guide/error-handling.mdx index 7c4c292b68..019d539c95 100644 --- a/src/content/docs/fr/5x/guide/error-handling.mdx +++ b/src/content/docs/fr/5x/guide/error-handling.mdx @@ -14,6 +14,8 @@ handler so you don't need to write your own to get started. Il est important de s'assurer qu'Express attrape toutes les erreurs qui se produisent lorsque exécute des gestionnaires de routes et des middleware. +### Errors in synchronous code + Les erreurs qui se produisent dans le code synchrone dans les gestionnaires de route et les middleware ne nécessitent aucun travail supplémentaire. If synchronous code throws an error, then Express will catch and process it. Par exemple : @@ -32,51 +34,24 @@ app.get('/', (req: Request, res: Response) => { }); ``` -For errors returned from asynchronous functions invoked by route handlers -and middleware, you must pass them to the `next()` function, where Express will -catch and process them. Par exemple : - -```js -app.get('/', (req, res, next) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` +### Errors in asynchronous code -```ts -import { type Request, type Response, type NextFunction } from 'express'; - -app.get('/', (req: Request, res: Response, next: NextFunction) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` - -À partir de Express 5, les gestionnaires de route et les middleware qui retournent une Promise -appelleront automatiquement `next(value)` quand ils rejettent ou lancent une erreur. -Par exemple : +The recommended way to write asynchronous handlers is with `async` functions. +Route handlers and middleware that return a Promise call `next(value)` +automatically when they reject or throw an error, and `async` functions always +return a Promise, so their errors reach Express with no extra work. Par exemple : ```js -app.get('/user/:id', async (req, res, next) => { +app.get('/user/:id', async (req, res) => { const user = await getUserById(req.params.id); res.send(user); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', async (req: Request, res: Response) => { const user = await getUserById(req.params.id); res.send(user); }); @@ -90,49 +65,41 @@ If you pass anything to the `next()` function (except the string `'route'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. -Si le callback dans une séquence ne fournit aucune donnée, seulement des erreurs, vous pouvez simplifier -ce code comme suit: +### Working with promise chains + +If you build a promise chain instead of using an `async` function, return the +promise from the handler and Express will likewise call `next` automatically +when it rejects: ```js -app.get('/', [ - function (req, res, next) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req, res) { - res.send('OK'); - }, -]); +app.get('/', (req, res) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/', [ - function (req: Request, res: Response, next: NextFunction) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req: Request, res: Response) { - res.send('OK'); - }, -]); +app.get('/', (req: Request, res: Response) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` -Dans l'exemple ci-dessus, `next` est fourni comme callback pour `fs.writeFile`, -qui est appelé avec ou sans erreurs. S'il n'y a pas d'erreur, le second -est exécuté, sinon Express attrape et traite l'erreur. - -Vous devez attraper les erreurs qui se produisent dans le code asynchrone invoqué par les gestionnaires de route ou -middleware et les passer à Express pour le traitement. Par exemple : +If the promise is not returned, Express does not know it exists, and you must +route the error yourself by providing `next` as the final catch handler. +Without it, the rejection would be unhandled and crash the process: ```js app.get('/', (req, res, next) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` @@ -140,31 +107,32 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` -L'exemple ci-dessus utilise un bloc `try...catch` pour attraper des erreurs dans le code -asynchrone et les passer à Express. Si le bloc `try...catch` -était omis, Express ne attrapera pas l'erreur car il ne fait pas partie du code du gestionnaire -synchrone. +This works because if a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, `.catch` calls its handler with the error as the first argument, which is exactly the argument `next` expects, so the error reaches Express. -Utilise des promesses pour éviter les frais généraux du bloc `essayer...catch` ou lorsque tu utilises les fonctions -qui renvoient des promesses. Par exemple : +### Working with callback APIs + +Errors produced by callback-based APIs, such as those in `node:fs`, are not +thrown and are not part of any promise. The callback receives them as its first +argument, and you must pass them to the `next()` function yourself, where +Express will catch and process them. Par exemple : ```js app.get('/', (req, res, next) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` @@ -172,17 +140,46 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` -Puisque les promesses attrapent automatiquement à la fois les erreurs synchrones et les promesses rejetées, -vous pouvez simplement fournir `next` car le gestionnaire de capture final et Express attrapera des erreurs, -parce que le gestionnaire de capture est donné l'erreur comme premier argument. +Si le callback dans une séquence ne fournit aucune donnée, seulement des erreurs, vous pouvez simplifier +ce code comme suit: + +```js +app.get('/', [ + function (req, res, next) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req, res) { + res.send('OK'); + }, +]); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', [ + function (req: Request, res: Response, next: NextFunction) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req: Request, res: Response) { + res.send('OK'); + }, +]); +``` + +Dans l'exemple ci-dessus, `next` est fourni comme callback pour `fs.writeFile`, +qui est appelé avec ou sans erreurs. S'il n'y a pas d'erreur, le second +est exécuté, sinon Express attrape et traite l'erreur. Vous pouvez également utiliser une chaîne de gestionnaires pour vous fier à l'erreur synchrone attrapant, en réduisant le code asynchrone à quelque chose de trivial. Par exemple : @@ -219,14 +216,49 @@ app.get('/', [ ]); ``` -L'exemple ci-dessus a quelques déclarations triviales de l'appel `readFile` -. Si `readFile` cause une erreur, alors il passe l'erreur à Express, sinon vous +The above example contains a couple of trivial statements following the `readFile` +call. Si `readFile` cause une erreur, alors il passe l'erreur à Express, sinon vous revenez rapidement au monde de la gestion des erreurs synchrones dans le prochain gestionnaire de la chaîne. Ensuite, l'exemple ci-dessus tente de traiter les données. Si cela échoue, alors le gestionnaire d'erreurs synchrone l'attrapera. Si vous aviez fait ce traitement à l'intérieur de la callback `readFile`, alors l'application pourrait quitter et les gestionnaires d'erreur Express ne s'exécuteraient pas. +Finally, for asynchronous code that provides no error-first callback, such as a +timer, catch errors inside the asynchronous code itself and pass them to +Express: + +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', (req: Request, res: Response, next: NextFunction) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +L'exemple ci-dessus utilise un bloc `try...catch` pour attraper des erreurs dans le code +asynchrone et les passer à Express. Si le bloc `try...catch` +était omis, Express ne attrapera pas l'erreur car il ne fait pas partie du code du gestionnaire +synchrone. + Quelle que soit la méthode que vous utilisez, si vous voulez que les gestionnaires d'erreur Express soient appelés et que l'application survive, vous devez vous assurer qu'Express reçoit l'erreur. @@ -424,7 +456,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Aussi dans cet exemple, `clientErrorHandler` est défini comme suit ; dans ce cas, l'erreur est explicitement passée au suivant. -Notez que lorsque _not_ appelez "next" dans une fonction de gestion des erreurs, vous êtes responsable de l'écriture (et de la fin) de la réponse. Sinon, ces demandes seront « bloquées » et ne seront pas admissibles au ramassage des déchets. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Sinon, ces demandes seront « bloquées » et ne seront pas admissibles au ramassage des déchets. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/fr/5x/guide/overriding-express-api.mdx b/src/content/docs/fr/5x/guide/overriding-express-api.mdx index 3a4e12e346..3b1e7bb173 100644 --- a/src/content/docs/fr/5x/guide/overriding-express-api.mdx +++ b/src/content/docs/fr/5x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -L'API Express se compose de différentes méthodes et propriétés sur les objets de requête et de réponse. Celles-ci sont héritées du prototype. Il y a deux points d'extension pour l'API Express : +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. Celles-ci sont héritées du prototype. Il y a deux points d'extension pour l'API Express : 1. Les prototypes globaux à `express.request` et `express.response`. 2. Prototypes spécifiques à l'application à `app.request` et `app.response`. diff --git a/src/content/docs/fr/5x/guide/routing.mdx b/src/content/docs/fr/5x/guide/routing.mdx index b2090f460c..d12bea79ee 100644 --- a/src/content/docs/fr/5x/guide/routing.mdx +++ b/src/content/docs/fr/5x/guide/routing.mdx @@ -13,7 +13,7 @@ par exemple, `app. et()` pour gérer les requêtes GET et `app.post` pour gérer see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. En d'autres termes, l'application "écoute" les requêtes qui correspondent à la(les) route(s) spécifiée(s) et à la(les) méthode(s), et quand il détecte une correspondance, il appelle la fonction de rappel spécifiée. +En d'autres termes, l'application "écoute" les requêtes qui correspondent à la(les) route(s) spécifiée(s) et à la(les) méthode(s), et quand il détecte une correspondance, il appelle la fonction de rappel spécifiée. En d'autres termes, l'application "écoute" les requêtes qui correspondent à la(les) route(s) spécifiée(s) et à la(les) méthode(s), et quand il détecte une correspondance, il appelle la fonction de rappel spécifiée. En fait, les méthodes de routage peuvent avoir plus d'une fonction de rappel en tant qu'arguments. Avec plusieurs fonctions de rappel, il est important de fournir `next` comme argument à la fonction de callback puis appeler `next()` dans le corps de la fonction pour distribuer le contrôle @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express supporte les méthodes qui correspondent à toutes les méthodes de requête HTTP : `get`, `post`, et ainsi de suite. For a full list, see [app.METHOD](/api/application#appmethod). -Il y a une méthode de routage spéciale, `app.all()`, utilisée pour charger les fonctions du middleware à un chemin pour _toutes_ les méthodes de requête HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +Il y a une méthode de routage spéciale, `app.all()`, utilisée pour charger les fonctions du middleware à un chemin pour _toutes_ les méthodes de requête HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Chemins de la route -Les chemins de la route, en combinaison avec une méthode de requête, définissent les points de terminaison à partir desquels les requêtes peuvent être faites. Les chemins de route peuvent être des chaînes de caractères ou des expressions régulières. +Les chemins de la route, en combinaison avec une méthode de requête, définissent les points de terminaison à partir desquels les requêtes peuvent être faites. Les chemins de route peuvent être des chaînes de caractères ou des expressions régulières. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -153,77 +153,9 @@ app.get('/random.text', (req: Request, res: Response) => { }); ``` -### Wildcards - -Les jokers correspondent à n'importe quel chemin après un préfixe. Ils doivent avoir un nom, tout comme les paramètres de trajet, et sont capturés sous la forme de tableaux de segments de chemins. - -```js -app.get('/files/*filepath', (req, res) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -Pour correspondre également au chemin de la racine, enveloppez le joker entre accolades : - -```js -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req, res) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req: Request, res: Response) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -### Segments optionnels - -Utilisez des accolades pour définir des segments optionnels dans un chemin d'itinéraire. Lorsque le segment n'est pas présent, le paramètre est omis de `req.params`. - -```js -app.get('/:file{.:ext}', (req, res) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/:file{.:ext}', (req: Request, res: Response) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -Les caractères `?`, `+`, `*`, `[]`et `()` sont réservés et ne peuvent pas être utilisés comme caractères littéraux dans les chemins de route. Utilisez `\` pour les échapper si nécessaire. +The characters `?`, `+`, `*`, `[]`, `()`, and `!` are reserved and cannot be used as literal characters in route paths, and braces are reserved for [optional segments](#optional-segments). Utilisez `\` pour les échapper si nécessaire. @@ -259,7 +191,11 @@ app.get(/.*fly$/, (req: Request, res: Response) => { ## Paramètres de la route -Les paramètres de la route sont des segments d'URL nommés qui sont utilisés pour capturer les valeurs spécifiées à leur position dans l'URL. Les valeurs capturées sont remplies dans l'objet `req.params`, avec le nom du paramètre route spécifié dans le chemin comme leurs clés respectives. +Les paramètres de la route sont des segments d'URL nommés qui sont utilisés pour capturer les valeurs spécifiées à leur position dans l'URL. Les valeurs capturées sont remplies dans l'objet `req.params`, avec le nom du paramètre route spécifié dans le chemin comme leurs clés respectives. They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces. + +### Named parameters + +Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below. ``` Route path: /users/:userId/books/:bookId @@ -293,7 +229,7 @@ app.get('/users/:userId/books/:bookId', sendParams); -Le nom des paramètres de route doit être composé de "mots caractères" ([A-Za-z0-9_]). +The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example `:"user-name"`. @@ -313,14 +249,122 @@ req.params: { "genus": "Prunus", "species": "persica" } -Les caractères Regexp ne sont pas pris en charge dans les chemins de route. Utilisez un tableau de chemins ou d'expressions régulières à la place. +Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as `:userId(\d+)`. Use an array of paths or a full regular expression instead. Voir la [syntaxe correspondante à la route des chemins](/en/guide/migrating-5#path-syntax) pour plus d'informations. +### Wildcards + +Les jokers correspondent à n'importe quel chemin après un préfixe. Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string. + +```js +app.get('/files/*filepath', (req, res) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +Pour correspondre également au chemin de la racine, enveloppez le joker entre accolades : + +```js +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req, res) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req: Request, res: Response) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +### Segments optionnels + +Utilisez des accolades pour définir des segments optionnels dans un chemin d'itinéraire. Lorsque le segment n'est pas présent, le paramètre est omis de `req.params`. + +```js +app.get('/:file{.:ext}', (req, res) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/:file{.:ext}', (req: Request, res: Response) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters: + +```js +app.get('/user/\{:id}', (req, res) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req, res) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/user/\{:id}', (req: Request, res: Response) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req: Request, res: Response) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +Ne confondez pas la position de la barre oblique dans le chemin de la route avec le [paramètre `strict routing`](/api/application/#application-settings), qui concerne l'URL de la requête : il contrôle si une URL se terminant par une barre oblique que le chemin de la route n'exige pas correspond quand même. Par exemple, une requête vers `/order/` correspond par défaut à la route `/order{/:id}`, mais renvoie une erreur 404 lorsque strict routing est activé ; la barre oblique finale de `/user/` n'est pas concernée car la route `/user/\{:id}` l'exige. Toutes les requêtes commentées dans les exemples ci-dessus se comportent de la même manière quel que soit ce paramètre.## Route handlersYou can provide multiple callback functions that + ## Gestionnaires de routes -Vous pouvez fournir plusieurs fonctions de rappel qui se comportent comme [middleware](/guide/using-middleware) pour traiter une requête. La seule exception est que ces callbacks peuvent appeler `next('route')` pour contourner les rappels de route restants. Vous pouvez utiliser ce mécanisme pour imposer des conditions préalables sur une route, passent ensuite le contrôle aux routes suivantes s'il n'y a pas de raison de poursuivre l'itinéraire courant. +Vous pouvez fournir plusieurs fonctions de rappel qui se comportent comme [middleware](/guide/using-middleware) pour traiter une requête. La seule exception est que ces callbacks peuvent appeler `next('route')` pour contourner les rappels de route restants. Vous pouvez utiliser ce mécanisme pour imposer des conditions préalables sur une route, passent ensuite le contrôle aux routes suivantes s'il n'y a pas de raison de poursuivre l'itinéraire courant.```js +app.get('/user/:id', (req, res, next) => { +if (req.params.i + +```` ```js app.get('/user/:id', (req, res, next) => { @@ -333,7 +377,7 @@ app.get('/user/:id', (req, res, next) => { app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0'); }); -``` +```` ```ts import { type Request, type Response, type NextFunction } from 'express'; @@ -355,15 +399,17 @@ Dans cet exemple : - `GET /user/5` → géré par la première route → envoie "Utilisateur 5" - `GET /user/0` → première route appelle `next('route')`, passe à la prochaine route correspondant à `/user/:id` -Les gestionnaires de routes peuvent être sous la forme d'une fonction, d'un tableau de fonctions, ou de combinaisons des deux, comme indiqué dans les exemples suivants. +Les gestionnaires de routes peuvent être sous la forme d'une fonction, d'un tableau de fonctions, ou de combinaisons des deux, comme indiqué dans les exemples suivants.A single callback function can handle a route. For example:```js + +```` -Une seule fonction de rappel peut gérer une route. Par exemple : +Une combinaison de fonctions indépendantes et de tableaux de fonctions peut gérer une route. ```js app.get('/example/a', (req, res) => { res.send('Hello from A!'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -403,7 +449,7 @@ app.get( ); ``` -Un tableau de fonctions de rappel peut gérer une route. Par exemple : +Un tableau de fonctions de rappel peut gérer une route. ```js const cb0 = function (req, res, next) { @@ -497,26 +543,32 @@ app.get( ## Méthodes de réponse -Les méthodes de l'objet de réponse (`res`) dans la table suivante peuvent envoyer une réponse au client et terminer le cycle de réponse de la requête. Si aucune de ces méthodes n'est appelée à partir d'un gestionnaire d'itinéraire, la requête du client sera suspendue. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. Si aucune de ces méthodes n'est appelée à partir d'un gestionnaire d'itinéraire, la requête du client sera suspendue.| Method | Description| Method | Description -| Méthode | Libellé | -| ----------------------------------------------- | ------------------------------------------------------------------------------------------------- | -| [res.download()](/api/response#resdownload) | Demander au téléchargement un fichier. | -| [res.end()](/api/response#resend) | Terminer le processus de réponse. | -| [res.json()](/api/response#resjson) | Envoyer une réponse JSON. | -| [res.jsonp()](/api/response#resjsonp) | Envoyer une réponse JSON avec le support JSONP. | -| [res.redirect()](/api/response#resredirect) | Rediriger une requête. | -| [res.render()](/api/response#resrender) | Afficher un modèle de vue. | -| [res.send()](/api/response#ressend) | Envoyer une réponse de différents types. | -| [res.sendFile()](/api/response#ressendfile) | Envoyer un fichier en tant que flux octet. | -| [res.sendStatus()](/api/response#ressendstatus) | Définit le code de statut de la réponse et envoie sa représentation en tant que corps de réponse. | +| | | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/api/response#resdownload) | Demander au téléchargement un fichier. | +| [res.end()](/api/response#resend) | Terminer le processus de réponse. | +| [res.json()](/api/response#resjson) | Envoyer une réponse JSON. | +| [res.jsonp()](/api/response#resjsonp) | Envoyer une réponse JSON avec le support JSONP. | +| | Rediriger une requête. | +| [res.render()](/api/response#resrender) | Afficher un modèle de vue. | +| [res.send()](/api/response#ressend) | Envoyer une réponse de différents types. | +| [res.sendFile()](/api/response#ressendfile) | Envoyer un fichier en tant que flux octet. | +| [res.sendStatus()](/api/response#ressendstatus) | Définit le code de statut de la réponse et envoie sa représentation en tant que corps de réponse. \|## app.route()You can create chainable route handlers for a rou | ## app.route() Vous pouvez créer des gestionnaires de routes chaînables pour un chemin en utilisant `app.route()`. -Parce que le chemin est spécifié à un seul endroit, la création de routes modulaires est utile, tout comme la réduction de la redondance et des fautes de frappe. Pour plus d'informations sur les routes, voir : [Documentation de Router()](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router).Here is an example of chained route handlers that are defined by us + +Voici un exemple de gestionnaires de routes enchaînés qui sont définis en utilisant `app.route()`.```js +app +.route('/book') +.get((req, res) => { +res.send('Ge -Voici un exemple de gestionnaires de routes enchaînés qui sont définis en utilisant `app.route()`. +```` ```js app @@ -530,7 +582,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -550,9 +602,9 @@ app ## Routeur -Utilisez la classe `express.Router` pour créer des gestionnaires de route modulaires et montables. Une instance `Router` est un système complet de middleware et de routage ; pour cette raison, elle est souvent appelée "mini-app". +Utilisez la classe `express.Router` pour créer des gestionnaires de route modulaires et montables. Une instance `Router` est un système complet de middleware et de routage ; pour cette raison, elle est souvent appelée "mini-app".The following example creates a router as a module, loads a middlewThe following example creates a router as a module, loads a middlew -L'exemple suivant crée un routeur en tant que module, charge une fonction middleware dedans, définit quelques routes, et monte le module routeur sur un chemin dans l'application principale. +L'exemple suivant crée un routeur en tant que module, charge une fonction middleware dedans, définit quelques routes, et monte le module routeur sur un chemin dans l'application principale.Create a router file named `birds.js` in the app directory, with th Créez un fichier de routeur nommé `birds.js` dans le répertoire de l'application, avec le contenu suivant : @@ -645,10 +697,13 @@ import birds from './birds'; app.use('/birds', birds); ``` -L'application sera maintenant en mesure de traiter les demandes vers `/birds` et `/birds/about`, ainsi que d'appeler la fonction middleware `timeLog` qui est spécifique à la route. +L'application sera maintenant en mesure de traiter les demandes vers `/birds` et `/birds/about`, ainsi que d'appeler la fonction middleware `timeLog` qui est spécifique à la route.But if the parent route `/birds` has path parameters, it will not b -Mais si la route parente `/birds` a des paramètres de chemin, elle ne sera pas accessible par défaut à partir des sous-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +Mais si la route parente `/birds` a des paramètres de chemin, elle ne sera pas accessible par défaut à partir des sous-routes. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter).```js +const router = express.Router({ mergeParams: true }); + +```` ```js const router = express.Router({ mergeParams: true }); -``` +```` diff --git a/src/content/docs/fr/5x/guide/using-middleware.mdx b/src/content/docs/fr/5x/guide/using-middleware.mdx index a7187ee798..cb6afa7dd4 100644 --- a/src/content/docs/fr/5x/guide/using-middleware.mdx +++ b/src/content/docs/fr/5x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Apprenez à utiliser les middleware dans les applications Express.j import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express est un framework web de routage et de middleware qui possède des fonctionnalités minimales : Une application Express est essentiellement une série d'appels de fonctions de middleware. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -Les fonctions _Middleware_ sont des fonctions qui ont accès à l'objet [request object](/api#req) (`req`), l'objet [réponse](/api#res) (`res`), et la prochaine fonction du middleware dans le cycle de réponse de l'application. La prochaine fonction du middleware est généralement dénotée par une variable nommée `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Les fonctions Middleware peuvent effectuer les tâches suivantes : - Exécuter n'importe quel code. -- Effectuez des modifications à la requête et aux objets de réponse. +- Modify the request and response objects. - Termine le cycle de réponse de la requête. -- Appeler la prochaine fonction du middleware dans la pile. +- Pass control to the next middleware function. -Si la fonction middleware actuelle ne met pas fin au cycle de réponse de requête, elle doit appeler `next()` pour passer le contrôle à la prochaine fonction du middleware. Sinon, la demande sera laissée en suspens. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Sinon, la demande sera laissée en suspens. Une application Express peut utiliser les types de middleware suivants : @@ -27,14 +32,15 @@ Une application Express peut utiliser les types de middleware suivants : - (#middleware.built-in) - [middleware de tierce partie](#middleware.third-party) -Vous pouvez charger le middleware au niveau de l'application et du routeur avec un chemin de montage optionnel. -Vous pouvez également charger une série de fonctions middleware ensemble, ce qui crée une sous-pile du système middleware à un point de montage. +Vous pouvez charger le middleware au niveau de l'application et du routeur avec un chemin de montage optionnel. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Outil d'interface de l'application -Lier le middleware au niveau de l'application à une instance de l'objet [app object](/api#app) en utilisant `app.use()` et `app. Les fonctions ETHOD()`, où `METHOD` est la méthode HTTP de la requête que la fonction middleware gère (comme GET, PUT ou POST) en minuscule. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -Cet exemple montre une fonction middleware sans chemin de montage. La fonction est exécutée chaque fois que l'application reçoit une requête. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -Cet exemple montre une fonction middleware montée sur le chemin `/user/:id`. La fonction est exécutée pour n'importe quel type de requête HTTP -sur le chemin `/user/:id`. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Gestionnaires de routes + Cet exemple montre une route et sa fonction de gestion (système middleware). La fonction gère les requêtes GET vers le chemin `/user/:id`. ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Voici un exemple de chargement d'une série de fonctions middleware à un point de montage, avec un chemin de montage. -Il illustre une sous-pile middleware qui affiche les informations de requête pour tout type de requête HTTP vers le chemin `/user/:id`. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Les gestionnaires de routes vous permettent de définir plusieurs routes pour un chemin. L'exemple ci-dessous définit deux routes pour les requêtes GET vers le chemin `/user/:id`. La deuxième route ne posera aucun problème, mais elle ne sera jamais appelée parce que le premier parcours termine le cycle de réponse de la requête. +### Multiple route handlers -Cet exemple montre une sous-pile middleware qui gère les requêtes GET vers le chemin `/user/:id`. +Les gestionnaires de routes vous permettent de définir plusieurs routes pour un chemin. L'exemple ci-dessous définit deux routes pour les requêtes GET vers le chemin `/user/:id`. La deuxième route ne posera aucun problème, mais elle ne sera jamais appelée parce que le premier parcours termine le cycle de réponse de la requête. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -Pour sauter le reste des fonctions du middleware à partir d'une pile de middleware du routeur, appelez `next('route')` pour passer le contrôle à la route suivante. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ Pour sauter le reste des fonctions du middleware à partir d'une pile de middlew -Cet exemple montre une sous-pile middleware qui gère les requêtes GET vers le chemin `/user/:id`. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Les Middleware peuvent également être déclarés dans un tableau pour être réutilisables. +### Reusable middleware arrays -Cet exemple montre un tableau avec une sous-pile middleware qui gère les requêtes GET vers le chemin `/user/:id` +Middleware functions can also be grouped into arrays for better reusability. Cet exemple montre un tableau avec une sous-pile middleware qui gère les requêtes GET vers le chemin `/user/:id` ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,14 +280,14 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## middleware au niveau du routeur -Le middleware au niveau du routeur fonctionne de la même manière que le middleware au niveau de l'application, sauf qu'il est lié à une instance de `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); @@ -319,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -369,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -419,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -440,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -Pour sauter le reste des fonctions du middleware du routeur, appelez `next('router')` -pour passer le contrôle hors de l'instance du routeur. +### Skipping out of a router + +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. -Cet exemple montre une sous-pile middleware qui gère les requêtes GET vers le chemin `/user/:id`. +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -512,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Gestion des erreurs du middleware - - -La gestion d'erreurs du middleware prend toujours _four_ arguments. Vous devez fournir quatre arguments à -l'identifier comme une fonction de gestion des erreurs du middleware. Même si vous n'avez pas besoin d'utiliser l'objet `next` -, vous devez le spécifier pour maintenir la signature. Sinon, l'objet `next` sera -interprété comme un middleware normal et ne gérera pas les erreurs. - - - Définissez les fonctions du middleware de la même manière que les autres fonctions du middleware, sauf avec quatre arguments au lieu de trois, spécifiquement avec la signature `(err, req, res, next)`: ```js @@ -539,18 +543,30 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Pour plus de détails sur la gestion des erreurs du middleware, voir : [Gestion des erreurs](/guide/error-handling). + -## middleware intégré +La gestion d'erreurs du middleware prend toujours _four_ arguments. Vous devez fournir quatre arguments à +l'identifier comme une fonction de gestion des erreurs du middleware. Même si vous n'avez pas besoin d'utiliser l'objet `next` +, vous devez le spécifier pour maintenir la signature. Sinon, l'objet `next` sera +interprété comme un middleware normal et ne gérera pas les erreurs. + + + + -À partir de la version 4.x, Express ne dépend plus de [Connect](https://github.com/senchalabs/connect). Les fonctions du middleware -qui étaient précédemment incluses avec Express sont maintenant dans des modules séparés ; voir [la liste des fonctions du middleware](https://github.com/senchalabs/connect#middleware). +For more information, see the [Error handling](/guide/error-handling) guide. + + + +## middleware intégré Express a les fonctions internes suivantes : - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. -- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTE : Disponible avec Express 4.16.0+** -- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTE : Disponible avec Express 4.16.0+** +- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. +- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. ## middleware de tierce partie @@ -591,4 +607,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Pour une liste partielle des fonctions middleware tierces qui sont couramment utilisées avec Express, voir : [middleware de tierce] (../resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/fr/5x/guide/using-template-engines.mdx b/src/content/docs/fr/5x/guide/using-template-engines.mdx index 6e8a650917..2d3d4be633 100644 --- a/src/content/docs/fr/5x/guide/using-template-engines.mdx +++ b/src/content/docs/fr/5x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Utiliser les moteurs de gabarits avec Express -description: Découvrez comment intégrer et utiliser des moteurs de gabarits tels que Pug, Handlebars et EJS avec Express.js pour rendre les pages HTML dynamiques efficacement. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ Un _moteur de modèle_ vous permet d'utiliser des fichiers de modèles statiques dans un fichier de gabarit par des valeurs réelles, et transforme le modèle en un fichier HTML envoyé au client. Cette approche facilite la conception d'une page HTML. -Le [générateur d'application Express](/starter/generator) utilise [Pug](https://pugjs.org/api/getting-started.html) par défaut, mais il supporte aussi [Handlebars](https://www.npmjs.com/package/handlebars), et [EJS](https://www.npmjs.com/package/ejs), entre autres. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, le répertoire où se trouvent les fichiers de modèle. Ex. : `app.set('vues', './views')`. Par défaut, le répertoire `views` se trouve à la racine de l'application. - `voir le moteur`, le moteur de gabarit à utiliser. Par exemple, pour utiliser le moteur de gabarit Pug : `app.set('moteur de vue', 'pug')`. -Ensuite, installez le paquet npm correspondant au moteur de gabarits ; par exemple pour installer Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ qui `res.render()` appelle pour rendre le code du gabarit. Certains moteurs de gabarits ne suivent pas cette convention. La bibliothèque [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) suit cette convention en mappant tous les moteurs de gabarits populaires Node.js, et fonctionne donc parfaitement dans Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/fr/5x/guide/writing-middleware.mdx b/src/content/docs/fr/5x/guide/writing-middleware.mdx index 1687ffc973..f7fcb70b24 100644 --- a/src/content/docs/fr/5x/guide/writing-middleware.mdx +++ b/src/content/docs/fr/5x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Apprenez à écrire des fonctions personnalisées de middleware pou --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Aussi, la fonction callback de la route du chemin racine utilise la propriété que la fonction middleware ajoute à `req` (l'objet de requête). L'application utilise maintenant la fonction middleware `requestTime`. @@ -170,8 +171,8 @@ La fonction du middleware `myLogger` affiche simplement un message, passe ensuit ### Middleware fonction requestTime -Ensuite, nous allons créer une fonction middleware appelée "requestTime" et ajouter une propriété appelée `requestTime` -à l'objet requête. +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -391,9 +392,13 @@ qui ne gère pas les autres fonctions de routage. -Parce que vous avez accès à l'objet requête, à l'objet de réponse, à la prochaine fonction du middleware dans la pile, et à l'ensemble du nœud. s API, les possibilités avec les fonctions du middleware sont infinies. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Pour plus d'informations sur le middleware Express, voir : [Utiliser un middleware Express](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Logiciel middleware configurable diff --git a/src/content/docs/fr/5x/starter/basic-routing.mdx b/src/content/docs/fr/5x/starter/basic-routing.mdx index 52a6d1de2f..2b4a3ea620 100644 --- a/src/content/docs/fr/5x/starter/basic-routing.mdx +++ b/src/content/docs/fr/5x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Apprenez les fondamentaux du routage dans les applications Express. --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ désigne la façon dont une application répond à une requête client à un point de terminaison particulier, qui est une URI (ou un chemin) et une méthode spécifique de requête HTTP (GET, POST, etc.). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -Pour plus de détails sur le routage, consultez le [guide de routage](/en/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/fr/5x/starter/faq.mdx b/src/content/docs/fr/5x/starter/faq.mdx index 21737d793f..2074466331 100644 --- a/src/content/docs/fr/5x/starter/faq.mdx +++ b/src/content/docs/fr/5x/starter/faq.mdx @@ -3,6 +3,8 @@ title: Foire Aux Questions description: Retrouvez les réponses aux questions les plus fréquemment posées sur Express.js, y compris les sujets sur la structure de l'application, les modèles, l'authentification, les moteurs de gabarit, la gestion des erreurs, et plus encore. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## Comment structurer ma candidature ? Il n'y a pas de réponse définitive à cette question. La réponse dépend @@ -42,7 +44,11 @@ Pour normaliser les interfaces du moteur de gabarits et la mise en cache, consul [consolidate.js](https://github.com/visionmedia/consolidate.js) pour plus de support. Les moteurs de gabarits non listés peuvent toujours supporter la signature Express. -Pour plus d'informations, voir [Utilisation de moteurs de gabarits avec Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## Comment gérer 404 réponses? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Pour plus d'informations, voir [Gestion des erreurs](/en/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Comment rendre le HTML simple ? diff --git a/src/content/docs/fr/5x/starter/installing.mdx b/src/content/docs/fr/5x/starter/installing.mdx index 3691ca3c40..293a4363e8 100644 --- a/src/content/docs/fr/5x/starter/installing.mdx +++ b/src/content/docs/fr/5x/starter/installing.mdx @@ -70,7 +70,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/fr/5x/starter/static-files.mdx b/src/content/docs/fr/5x/starter/static-files.mdx index b1fffa2e01..0a7402e0c7 100644 --- a/src/content/docs/fr/5x/starter/static-files.mdx +++ b/src/content/docs/fr/5x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Comprendre comment servir les fichiers statiques comme les images, --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Pour servir des fichiers statiques tels que des images, des fichiers CSS et des fichiers JavaScript, utilisez la fonction middleware intégrée `express.static` dans Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + Pour plus de détails sur la fonction `serve-static` et ses options, voir [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/it/4x/guide/debugging.mdx b/src/content/docs/it/4x/guide/debugging.mdx index 377c7d0144..7a2241a606 100644 --- a/src/content/docs/it/4x/guide/debugging.mdx +++ b/src/content/docs/it/4x/guide/debugging.mdx @@ -4,6 +4,7 @@ description: Scopri come abilitare e utilizzare i log di debug nelle applicazion --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; Per vedere tutti i log interni utilizzati in Express, imposta la variabile d'ambiente `DEBUG` su `express:*` quando lancia la tua app. @@ -86,22 +87,119 @@ Quando viene fatta una richiesta all'applicazione, vedrete i registri specificat Per vedere i log solo dall'implementazione del router, imposta il valore di `DEBUG` su `express:router`. Allo stesso modo, per vedere i log solo dall'implementazione dell'applicazione, imposta il valore di `DEBUG` su `express:application`, e così via. -## Applicazioni generate da `express` +## Using `debug` in your own code -Un'applicazione generata dal comando `express` utilizza il modulo `debug` e il suo namespace di debug è indirizzato al nome dell'applicazione. +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: -Ad esempio, se hai generato l'app con `$ express sample-app`, puoi abilitare le istruzioni di debug con il seguente comando: + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; + +const debug = debugModule('myapp:server'); +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` È possibile specificare più di uno spazio dei nomi di debug assegnando una lista di nomi separati da virgole: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,express:router node index.js +``` + +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*" } +} ``` +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Opzioni avanzate Quando si esegue attraverso Node.js, è possibile impostare alcune variabili di ambiente che cambieranno il comportamento della registrazione di debug: diff --git a/src/content/docs/it/4x/guide/error-handling.mdx b/src/content/docs/it/4x/guide/error-handling.mdx index 369e52e913..c177a9db64 100644 --- a/src/content/docs/it/4x/guide/error-handling.mdx +++ b/src/content/docs/it/4x/guide/error-handling.mdx @@ -62,14 +62,16 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -A partire da Express 5, i gestori del percorso e il middleware che restituiscono una Promise -chiameranno automaticamente `next(value)` quando rifiutano o generano un errore. -Per esempio: +Errors from rejected promises are not passed to `next` automatically, and this includes `async` functions: if an `async` route handler throws or awaits a rejected promise, the rejection is unhandled, which crashes the process on current Node.js versions. You must catch the error yourself and pass it to Express: ```js app.get('/user/:id', async (req, res, next) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` @@ -77,14 +79,22 @@ app.get('/user/:id', async (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` -Se `getUserById` genera un errore o rifiuta, `next` verrà chiamato con -l'errore generato o il valore rifiutato. Se non viene fornito alcun valore rifiutato, `next` -verrà chiamato con un oggetto di errore predefinito fornito dal router Express. + + +Consider [updating to Express 5](/guide/migrating-5), where route handlers and middleware that +return a Promise call `next(value)` automatically when they reject or throw an error, making the +`try...catch` above unnecessary. + + Se passi qualcosa alla funzione `next()` (tranne la stringa `'route'`), Express considera la richiesta corrente come un errore e salterà qualsiasi @@ -180,9 +190,7 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Dal momento che le promesse catturano automaticamente entrambi gli errori sincroni e le promesse rifiutate, -puoi semplicemente fornire `next` come il gestore finale di cattura e Express catturerà errori, -perché al gestore della cattura viene dato l'errore come primo argomento. +If a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, passing `next` as the handler is enough: `.catch` calls it with the error as its first argument, which is exactly the argument `next` expects, so the error reaches Express. Si potrebbe anche utilizzare una catena di gestori per fare affidamento su errore sincrono catching, riducendo il codice asincrono a qualcosa di banale. Per esempio: @@ -219,8 +227,8 @@ app.get('/', [ ]); ``` -L'esempio precedente ha un paio di istruzioni banali dalla chiamata `readFile` -. Se `readFile` causa un errore, allora passa l'errore a Express, altrimenti +The above example contains a couple of trivial statements following the `readFile` +call. Se `readFile` causa un errore, allora passa l'errore a Express, altrimenti torna rapidamente al mondo della gestione sincrona degli errori nel prossimo gestore nella catena. Poi, l'esempio di cui sopra cerca di elaborare i dati. Se questo fallisce, il gestore di errori sincroni lo catturerà. Se avessi fatto questa elaborazione all'interno di @@ -424,7 +432,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Anche in questo esempio, `clientErrorHandler` è definito come segue; in questo caso, l'errore viene esplicitamente passato a quello successivo. -Nota che quando _non_ chiama "next" in una funzione di gestione degli errori, sei responsabile della scrittura (e della fine) della risposta. In caso contrario, tali richieste saranno "appese" e non saranno ammissibili per la raccolta rifiuti. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. In caso contrario, tali richieste saranno "appese" e non saranno ammissibili per la raccolta rifiuti. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/it/4x/guide/overriding-express-api.mdx b/src/content/docs/it/4x/guide/overriding-express-api.mdx index c662a827b2..739ec2f203 100644 --- a/src/content/docs/it/4x/guide/overriding-express-api.mdx +++ b/src/content/docs/it/4x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -L'API Express è composta da vari metodi e proprietà su richiesta e oggetti di risposta. Questi sono ereditati dal prototipo. Ci sono due punti di estensione per l'API Express: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. Questi sono ereditati dal prototipo. Ci sono due punti di estensione per l'API Express: 1. I prototipi globali in `express.request` e `express.response`. 2. prototipi specifici per app su `app.request` e `app.response`. diff --git a/src/content/docs/it/4x/guide/routing.mdx b/src/content/docs/it/4x/guide/routing.mdx index 942a6bad68..5a11eb4756 100644 --- a/src/content/docs/it/4x/guide/routing.mdx +++ b/src/content/docs/it/4x/guide/routing.mdx @@ -13,7 +13,7 @@ per esempio, `app. et()` per gestire le richieste GET e `app.post` per gestire l see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. In altre parole, l'applicazione "ascolta" per le richieste che corrispondono ai percorsi e ai metodi specificati, e quando rileva una corrispondenza, chiama la funzione di callback specificata. +In altre parole, l'applicazione "ascolta" per le richieste che corrispondono ai percorsi e ai metodi specificati, e quando rileva una corrispondenza, chiama la funzione di callback specificata. In altre parole, l'applicazione "ascolta" per le richieste che corrispondono ai percorsi e ai metodi specificati, e quando rileva una corrispondenza, chiama la funzione di callback specificata. Infatti, i metodi di routing possono avere più di una funzione di callback come argomenti. Con funzioni di callback multiple, è importante fornire `next` come argomento alla funzione di callback e poi chiamare `next()` all'interno del corpo della funzione per consegnare il controllo @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express supporta metodi che corrispondono a tutti i metodi di richiesta HTTP: `get`, `post`, e così via. For a full list, see [app.METHOD](/api/application#appmethod). -C'è un metodo di routing speciale, `app.all()`, utilizzato per caricare le funzioni middleware in un percorso per _tutti_ i metodi di richiesta HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +C'è un metodo di routing speciale, `app.all()`, utilizzato per caricare le funzioni middleware in un percorso per _tutti_ i metodi di richiesta HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Percorsi di rotta -Percorsi di percorso, in combinazione con un metodo di richiesta, definire gli endpoint in cui le richieste possono essere fatte. I tracciati del percorso possono essere stringhe, motivi di stringa o espressioni regolari. +Percorsi di percorso, in combinazione con un metodo di richiesta, definire gli endpoint in cui le richieste possono essere fatte. I tracciati del percorso possono essere stringhe, motivi di stringa o espressioni regolari. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -235,6 +235,26 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => { }); ``` +A wildcard (`*`) on its own matches anything at its position, including entire subpaths. For example, this route path will match `/file/style.css` as well as `/file/javascripts/jquery.js`. Wildcards are unnamed, so the matched value is available as `req.params[0]` instead of a named parameter. + +```js +app.get('/file/*', (req, res) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/file/*', (req: Request, res: Response) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + ### Percorsi di percorso basati su espressioni regolari @@ -348,6 +368,14 @@ con un backslash aggiuntivo, ad esempio `\d+`. The [`*`](https://github.com/expressjs/express/issues/2495) character in regular expressions is not interpreted in the usual way. Come soluzione puoi usare `{0,}` invece di `*`. +Unlike named route parameters, wildcard (`*`) matches in [string patterns](#route-paths-based-on-string-patterns) and capture groups in regular expressions are unnamed: their values are available by position, as `req.params[0]`, `req.params[1]`, and so on. + +``` +Route path: /file/*/size/* +Request URL: http://localhost:3000/file/javascripts/jquery.js/size/large +req.params: { "0": "javascripts/jquery.js", "1": "large" } +``` + ## Gestori del percorso È possibile fornire più funzioni di callback che si comportano come [middleware](/guide/using-middleware) per gestire una richiesta. L'unica eccezione è che questi callback potrebbero invocare `next('route')` per bypassare i rimanenti callback del percorso. È possibile utilizzare questo meccanismo per imporre condizioni preliminari su un percorso, poi passare il controllo ai percorsi successivi se non c'è motivo di procedere con il percorso corrente. @@ -387,7 +415,7 @@ In questo esempio: I gestori del percorso possono essere nella forma di una funzione, una serie di funzioni, o combinazioni di entrambi, come mostrato negli esempi seguenti. -Una singola funzione di callback può gestire un percorso. Per esempio: +Più di una funzione di callback può gestire un percorso (assicurati di specificare l'oggetto `next`). Per esempio: ```js app.get('/example/a', (req, res) => { @@ -403,7 +431,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -Più di una funzione di callback può gestire un percorso (assicurati di specificare l'oggetto `next`). Per esempio: +Una combinazione di funzioni indipendenti e matrici di funzioni può gestire un percorso. Per esempio: ```js app.get( @@ -527,7 +555,7 @@ app.get( ## Metodi di risposta -I metodi sull'oggetto di risposta (`res`) nella tabella seguente possono inviare una risposta al client e terminare il ciclo di richiesta-risposta. Se nessuno di questi metodi è chiamato da un gestore del percorso, la richiesta del cliente sarà sospesa. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. Se nessuno di questi metodi è chiamato da un gestore del percorso, la richiesta del cliente sarà sospesa.| Method | Description | Metodo | Descrizione | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | @@ -544,7 +572,7 @@ I metodi sull'oggetto di risposta (`res`) nella tabella seguente possono inviare ## app.route() È possibile creare i gestori di rotte per un percorso utilizzando `app.route()`. -Poiché il percorso è specificato in una singola posizione, è utile creare percorsi modulari, così come ridurre la ridondanza e pneumatici. Per ulteriori informazioni sulle rotte, si veda: [Router() documentation](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router). Ecco un esempio di router incatenati che sono definiti utilizzando `app.route()`. @@ -580,9 +608,9 @@ app ## express.Router -Usa la classe `express.Router` per creare i gestori modulari e montabili. Un'istanza `Router` è un sistema di routing e middleware completo; per questo motivo è spesso chiamata "mini-app". +Usa la classe `express.Router` per creare i gestori modulari e montabili. Un'istanza `Router` è un sistema di routing e middleware completo; per questo motivo è spesso chiamata "mini-app".The following example creates a router as a module, loads a middlew -L'esempio seguente crea un router come modulo, carica una funzione middleware in esso, definisce alcuni percorsi e monta il modulo del router su un percorso nell'app principale. +L'esempio seguente crea un router come modulo, carica una funzione middleware in esso, definisce alcuni percorsi e monta il modulo del router su un percorso nell'app principale.Create a router file named `birds.js` in the app directory, with th Crea un file router chiamato `birds.js` nella directory delle app, con il seguente contenuto: @@ -677,7 +705,7 @@ app.use('/birds', birds); L'app sarà ora in grado di gestire le richieste di `/birds` e `/birds/about`, oltre a chiamare la funzione middleware `timeLog` che è specifica per il percorso. -Ma se il percorso principale `/birds` ha parametri di percorso, non sarà accessibile per impostazione predefinita dai sotto-percorsi. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +Ma se il percorso principale `/birds` ha parametri di percorso, non sarà accessibile per impostazione predefinita dai sotto-percorsi. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter). ```js const router = express.Router({ mergeParams: true }); diff --git a/src/content/docs/it/4x/guide/using-middleware.mdx b/src/content/docs/it/4x/guide/using-middleware.mdx index a6f3ae01ed..f30d64478b 100644 --- a/src/content/docs/it/4x/guide/using-middleware.mdx +++ b/src/content/docs/it/4x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Scopri come utilizzare middleware nelle applicazioni Express.js, tr import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express è un framework web routing e middleware che ha funzionalità minime proprie: Un'applicazione Express è essenzialmente una serie di chiamate di funzioni middleware. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -Le funzioni _Middleware_ sono funzioni che hanno accesso al [request object](/api#req) (`req`), il [response object](/api#res) (`res`), e la successiva funzione middleware nel ciclo request-response dell'applicazione. La funzione middleware successiva è comunemente indicata da una variabile chiamata `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Le funzioni Middleware possono eseguire le seguenti attività: - Esegue qualsiasi codice. -- Effettuare modifiche alla richiesta e agli oggetti di risposta. +- Modify the request and response objects. - Terminare il ciclo richiesta-risposta. -- Chiama la funzione middleware successiva nello stack. +- Pass control to the next middleware function. -Se la funzione middleware corrente non termina il ciclo richiesta-risposta, deve chiamare `next()` per passare il controllo alla successiva funzione middleware. In caso contrario, la richiesta sarà sospesa. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. In caso contrario, la richiesta sarà sospesa. Un'applicazione Express può utilizzare i seguenti tipi di middleware: @@ -27,14 +32,15 @@ Un'applicazione Express può utilizzare i seguenti tipi di middleware: - [Built-in middleware](#middleware.built-in) - [middleware di terze parti](#middleware.third-party) -È possibile caricare il middleware a livello di applicazione e router con un percorso di montaggio opzionale. -È inoltre possibile caricare una serie di funzioni middleware insieme, che crea una sottopila del sistema middleware in un punto di montaggio. +È possibile caricare il middleware a livello di applicazione e router con un percorso di montaggio opzionale. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Middleware a livello di applicazione -Associa il middleware di livello applicativo ad un'istanza del [app object](/api#app) usando `app.use()` e `app. ETHOD()` funzioni, dove `METHOD` è il metodo HTTP della richiesta che la funzione middleware gestisca (come GET, PUT, o POST) in minuscolo. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -Questo esempio mostra una funzione middleware senza percorso di montaggio. La funzione viene eseguita ogni volta che l'app riceve una richiesta. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -Questo esempio mostra una funzione middleware montata sul percorso `/user/:id`. La funzione viene eseguita per qualsiasi tipo di richiesta HTTP -sul percorso `/user/:id`. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Gestori del percorso + Questo esempio mostra un percorso e la sua funzione di gestore (sistema middleware). La funzione gestisce le richieste GET al percorso `/user/:id`. ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Ecco un esempio di caricamento di una serie di funzioni middleware in un punto di montaggio, con un percorso di montaggio. -Illustra un sub-stack middleware che stampa la richiesta di informazioni per qualsiasi tipo di richiesta HTTP al percorso `/user/:id`. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -I gestori del percorso consentono di definire percorsi multipli per un percorso. L'esempio sottostante definisce due percorsi per le richieste GET al percorso `/user/:id`. Il secondo percorso non causerà alcun problema, ma non verrà mai chiamato perché il primo percorso termina il ciclo richiesta-risposta. +### Multiple route handlers -Questo esempio mostra un sub-stack middleware che gestisce le richieste GET al percorso `/user/:id`. +I gestori del percorso consentono di definire percorsi multipli per un percorso. L'esempio sottostante definisce due percorsi per le richieste GET al percorso `/user/:id`. Il secondo percorso non causerà alcun problema, ma non verrà mai chiamato perché il primo percorso termina il ciclo richiesta-risposta. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -Per saltare il resto delle funzioni middleware da uno stack middleware router, chiama `next('route')` per passare il controllo al percorso successivo. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ Per saltare il resto delle funzioni middleware da uno stack middleware router, c -Questo esempio mostra un sub-stack middleware che gestisce le richieste GET al percorso `/user/:id`. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Middleware può anche essere dichiarato in un array per la riutilizzabilità. +### Reusable middleware arrays -Questo esempio mostra un array con un sub-stack middleware che gestisce le richieste GET al percorso `/user/:id` +Middleware functions can also be grouped into arrays for better reusability. Questo esempio mostra un array con un sub-stack middleware che gestisce le richieste GET al percorso `/user/:id` ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,19 +280,25 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Router-level middleware -Router-level middleware funziona allo stesso modo di application-level middleware, tranne che è legato ad un'istanza di `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); ``` +```ts +import express from 'express'; + +const router = express.Router(); +``` + Carica il middleware a livello router usando le funzioni `router.use()` e `router.METHOD()`. Il seguente esempio di codice replica il sistema middleware che viene mostrato sopra per il middleware a livello di applicazione, utilizzando il middleware a livello di router: @@ -313,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -363,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -413,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -434,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -Per saltare il resto delle funzioni middleware del router, chiama `next('router')` -per passare il controllo indietro dall'istanza del router. +### Skipping out of a router -Questo esempio mostra un sub-stack middleware che gestisce le richieste GET al percorso `/user/:id`. +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. + +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -506,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## middleware gestione errori - - -La gestione degli errori del middleware richiede sempre _four_ argomenti. È necessario fornire quattro argomenti per -identificarlo come una funzione middleware di gestione degli errori. Anche se non è necessario utilizzare l'oggetto `next` -, è necessario specificarlo per mantenere la firma. Otherwise, the `next` object will be -interpreted as regular middleware and will fail to handle errors. - - - Definire le funzioni middleware per la gestione degli errori allo stesso modo di altre funzioni middleware, tranne con quattro argomenti invece di tre, specificatamente con la firma `(err, req, res, next)`: ```js @@ -533,7 +543,20 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Per maggiori dettagli sulla gestione degli errori middleware, vedere [Gestione degli errori](/guide/error-handling). + + +La gestione degli errori del middleware richiede sempre _four_ argomenti. È necessario fornire quattro argomenti per +identificarlo come una funzione middleware di gestione degli errori. Anche se non è necessario utilizzare l'oggetto `next` +, è necessario specificarlo per mantenere la firma. Otherwise, the `next` object will be +interpreted as regular middleware and will fail to handle errors. + + + + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Middleware incorporato @@ -544,6 +567,8 @@ Express ha le seguenti funzioni middleware integrate: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. - [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTA: Disponibile con Express 4.16.0+** +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. **NOTE: Available with Express 4.17.0+** +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. **NOTE: Available with Express 4.17.0+** - [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTA: Disponibile con Express 4.16.0+** ## middleware di terze parti @@ -585,4 +610,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Per una lista parziale delle funzioni middleware di terze parti che sono comunemente usate con Express, vedere [middleware di terze parti](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/it/4x/guide/using-template-engines.mdx b/src/content/docs/it/4x/guide/using-template-engines.mdx index b871c2ebf6..fda726dba6 100644 --- a/src/content/docs/it/4x/guide/using-template-engines.mdx +++ b/src/content/docs/it/4x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Utilizzo di modelli di motori con Express -description: Scopri come integrare e utilizzare modelli di motori come Pug, Manubri ed EJS con Express.js per rendere le pagine HTML dinamiche in modo efficiente. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ Un motore _modello_ ti permette di utilizzare file di template statici nella tua in un modello di file con valori reali, e trasforma il modello in un file HTML inviato al client. Questo approccio rende più facile progettare una pagina HTML. -Il [generatore di applicazioni Express](/starter/generator) utilizza [Pug](https://pugjs.org/api/getting-started.html) come predefinito, ma supporta anche [Handlebars](https://www.npmjs.com/package/handlebars), e [EJS](https://www.npmjs.com/package/ejs), tra gli altri. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, la directory dove si trovano i file del modello. Eg: `app.set('views', './views')`. Questo valore predefinito è la directory `views` nella directory radice dell'applicazione. - `view engine`, il modello motore da usare. Ad esempio, per usare il motore modello Pug: `app.set('view engine', 'pug')`. -Quindi installare il corrispondente pacchetto npm del motore del modello; per esempio per installare Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ che `res.render()` chiama per rendere il codice del modello. Alcuni modelli di motori non seguono questa convenzione. La libreria [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) segue questa convenzione mappando tutti i popolari motori di template Node.js, e quindi funziona perfettamente all'interno di Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/it/4x/guide/writing-middleware.mdx b/src/content/docs/it/4x/guide/writing-middleware.mdx index 3cd8d64954..b7beae09e9 100644 --- a/src/content/docs/it/4x/guide/writing-middleware.mdx +++ b/src/content/docs/it/4x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Scopri come scrivere funzioni middleware personalizzate per le appl --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Le funzioni _Middleware_ sono funzioni che hanno accesso al [request object](/api#req) (`req`), il [response object](/api#res) (`res`), e la funzione `next` nel ciclo request-response dell'applicazione. La funzione `next` è una funzione nel router Express che, quando invocato, esegue il middleware con successo al middleware corrente. @@ -199,8 +200,8 @@ La funzione middleware `myLogger` semplicemente stampa un messaggio, poi passa l ### Richiesta funzione Middleware -Successivamente, creeremo una funzione middleware chiamata "requestTime" e aggiungeremo una proprietà chiamata `requestTime` -all'oggetto richiesta. +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -420,9 +421,13 @@ come un errore e salterà tutte le rimanenti funzioni di routing e middleware -Poiché hai accesso all'oggetto richiesta, all'oggetto risposta, alla funzione middleware successiva nello stack, e all'intero Node. s API, le possibilità con funzioni middleware sono infinite. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Per ulteriori informazioni su middleware Express, consultare: [Using Express middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Middleware configurabile diff --git a/src/content/docs/it/4x/starter/basic-routing.mdx b/src/content/docs/it/4x/starter/basic-routing.mdx index 03fb7c1f28..c80f433a3b 100644 --- a/src/content/docs/it/4x/starter/basic-routing.mdx +++ b/src/content/docs/it/4x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Impara i fondamenti del routing nelle applicazioni Express.js, tra --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ si riferisce alla determinazione di come un'applicazione risponde a una richiesta di client a un determinato endpoint, che è un URI (o percorso) e un metodo di richiesta HTTP specifico (GET, POST, e così via). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -Per maggiori dettagli sul routing, consulta la [guida di routing](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/it/4x/starter/faq.mdx b/src/content/docs/it/4x/starter/faq.mdx index 786c7e3932..19624af58b 100644 --- a/src/content/docs/it/4x/starter/faq.mdx +++ b/src/content/docs/it/4x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Trova le risposte alle domande più frequenti su Express.js, inclusi argomenti sulla struttura delle applicazioni, modelli, autenticazione, modelli motori, gestione degli errori e altro ancora. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## Come dovrei strutturare la mia applicazione? Non esiste una risposta definitiva a questa domanda. La risposta dipende da @@ -42,7 +44,11 @@ Per normalizzare i modelli di interfacce motore e caching, vedere il progetto [consolidate.js](https://github.com/visionmedia/consolidate.js) per il supporto. Motori modello non elencati potrebbero ancora supportare la firma Express. -Per ulteriori informazioni, vedere [Utilizzo di modelli di motori con Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## Come posso gestire 404 risposte? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Per ulteriori informazioni, vedere [Gestione degli errori](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Come faccio a rendere semplice HTML? diff --git a/src/content/docs/it/4x/starter/installing.mdx b/src/content/docs/it/4x/starter/installing.mdx index 86ad3c3f98..fdbabcd6d3 100644 --- a/src/content/docs/it/4x/starter/installing.mdx +++ b/src/content/docs/it/4x/starter/installing.mdx @@ -79,7 +79,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/it/4x/starter/static-files.mdx b/src/content/docs/it/4x/starter/static-files.mdx index 041dce63ce..a682560cf4 100644 --- a/src/content/docs/it/4x/starter/static-files.mdx +++ b/src/content/docs/it/4x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Comprendi come servire file statici come immagini, CSS e JavaScript --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Per servire file statici come immagini, file CSS e file JavaScript, utilizzare la funzione middleware integrata `express.static` in Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + Per maggiori dettagli sulla funzione `serve-static` e sulle sue opzioni, vedere [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/it/5x/guide/debugging.mdx b/src/content/docs/it/5x/guide/debugging.mdx index 377c7d0144..b745a54d5b 100644 --- a/src/content/docs/it/5x/guide/debugging.mdx +++ b/src/content/docs/it/5x/guide/debugging.mdx @@ -4,104 +4,218 @@ description: Scopri come abilitare e utilizzare i log di debug nelle applicazion --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -Per vedere tutti i log interni utilizzati in Express, imposta la variabile d'ambiente `DEBUG` su -`express:*` quando lancia la tua app. +To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*,router,router:*` when launching your app. Routing is handled by the separate [router](https://github.com/pillarjs/router) package, so its logs live under the `router` namespace and are not included in `express:*`. ```bash -$ DEBUG=express:* node index.js +$ DEBUG=express:*,router,router:* node index.js ``` Su Windows, utilizzare il comando corrispondente. ```bash -> $env:DEBUG = "express:*"; node index.js +> $env:DEBUG = "express:*,router,router:*"; node index.js ``` -L'esecuzione di questo comando nell'app predefinita generata dal [express generator](/starter/generator) stampa il seguente output: +Running this command on a small app with a JSON body parser and a mounted router prints the following output: + +```cjs title="index.cjs" +const express = require('express'); + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` + +```mjs title="index.mjs" +import express from 'express'; + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` ```bash -$ DEBUG=express:* node ./bin/www - express:router:route new / +0ms - express:router:layer new / +1ms - express:router:route get / +1ms - express:router:layer new / +0ms - express:router:route new / +1ms - express:router:layer new / +0ms - express:router:route get / +0ms - express:router:layer new / +0ms - express:application compile etag weak +1ms - express:application compile query parser extended +0ms - express:application compile trust proxy false +0ms - express:application booting in development mode +1ms - express:router use / query +0ms - express:router:layer new / +0ms - express:router use / expressInit +0ms - express:router:layer new / +0ms - express:router use / favicon +1ms - express:router:layer new / +0ms - express:router use / logger +0ms - express:router:layer new / +0ms - express:router use / jsonParser +0ms - express:router:layer new / +1ms - express:router use / urlencodedParser +0ms - express:router:layer new / +0ms - express:router use / cookieParser +0ms - express:router:layer new / +0ms - express:router use / stylus +90ms - express:router:layer new / +0ms - express:router use / serveStatic +0ms - express:router:layer new / +0ms - express:router use / router +0ms - express:router:layer new / +1ms - express:router use /users router +0ms - express:router:layer new /users +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms +$ DEBUG=express:*,router,router:* node index.js + express:application set "x-powered-by" to true +0ms + express:application set "etag" to 'weak' +3ms + express:application set "etag fn" to [Function: generateETag] +0ms + express:application set "env" to 'development' +1ms + express:application set "query parser" to 'simple' +0ms + express:application set "query parser fn" to [Function: parse] +0ms + express:application set "subdomain offset" to 2 +1ms + express:application set "trust proxy" to false +0ms + express:application set "trust proxy fn" to [Function: trustNone] +1ms + express:application booting in development mode +0ms + express:application set "view" to [Function: View] +0ms + express:application set "views" to '/projects/example/views' +1ms + express:application set "jsonp callback name" to 'callback' +0ms + router use '/' jsonParser +0ms + router:layer new '/' +0ms + router:route new '/' +0ms + router:layer new '/' +3ms + router:route get / +0ms + router:layer new '/' +1ms + router use '/users' router +4ms + router:layer new '/users' +0ms + router:route new '/' +1ms + router:layer new '/' +0ms + router:route get / +1ms + router:layer new '/' +1ms ``` Quando viene fatta una richiesta all'applicazione, vedrete i registri specificati nel codice Express: ```bash - express:router dispatching GET / +4h - express:router query : / +2ms - express:router expressInit : / +0ms - express:router favicon : / +0ms - express:router logger : / +1ms - express:router jsonParser : / +0ms - express:router urlencodedParser : / +1ms - express:router cookieParser : / +0ms - express:router stylus : / +0ms - express:router serveStatic : / +2ms - express:router router : / +2ms - express:router dispatching GET / +1ms - express:view lookup "index.pug" +338ms - express:view stat "/projects/example/views/index.pug" +0ms - express:view render "/projects/example/views/index.pug" +1ms + router dispatching GET /users +712ms + router jsonParser : /users +1ms + router trim prefix (/users) from url /users +2ms + router router /users : /users +0ms + router dispatching GET / +0ms +``` + +To see the logs only from the router implementation, set the value of `DEBUG` to `router,router:*`. Allo stesso modo, per vedere i log solo dall'implementazione dell'applicazione, imposta il valore di `DEBUG` su `express:application`, e così via. + +## Using `debug` in your own code + +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: + + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); ``` -Per vedere i log solo dall'implementazione del router, imposta il valore di `DEBUG` su `express:router`. Allo stesso modo, per vedere i log solo dall'implementazione dell'applicazione, imposta il valore di `DEBUG` su `express:application`, e così via. +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; -## Applicazioni generate da `express` +const debug = debugModule('myapp:server'); +const app = express(); -Un'applicazione generata dal comando `express` utilizza il modulo `debug` e il suo namespace di debug è indirizzato al nome dell'applicazione. +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); -Ad esempio, se hai generato l'app con `$ express sample-app`, puoi abilitare le istruzioni di debug con il seguente comando: +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` È possibile specificare più di uno spazio dei nomi di debug assegnando una lista di nomi separati da virgole: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,router node index.js ``` +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*,router,router:*" } +} +``` + +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Opzioni avanzate Quando si esegue attraverso Node.js, è possibile impostare alcune variabili di ambiente che cambieranno il comportamento della registrazione di debug: diff --git a/src/content/docs/it/5x/guide/error-handling.mdx b/src/content/docs/it/5x/guide/error-handling.mdx index 30297a0818..886011d35b 100644 --- a/src/content/docs/it/5x/guide/error-handling.mdx +++ b/src/content/docs/it/5x/guide/error-handling.mdx @@ -14,6 +14,8 @@ predefinito quindi non è necessario scrivere il proprio per iniziare. È importante garantire che Express colmi tutti gli errori che si verificano mentre gestisce le rotte e middleware. +### Errors in synchronous code + Gli errori che si verificano nel codice sincrono all'interno dei gestori del percorso e del middleware non richiedono lavoro aggiuntivo. Se il codice sincrono lancia un errore, allora Express catturerà ed elaborerà esso. Per esempio: @@ -32,51 +34,24 @@ app.get('/', (req: Request, res: Response) => { }); ``` -Per gli errori restituiti da funzioni asincrone invocate dai gestori degli itinerari -e middleware, devi passarli alla funzione `next()`, dove Express sarà -catturarli ed elaborarli. Per esempio: - -```js -app.get('/', (req, res, next) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` +### Errors in asynchronous code -```ts -import { type Request, type Response, type NextFunction } from 'express'; - -app.get('/', (req: Request, res: Response, next: NextFunction) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` - -A partire da Express 5, i gestori del percorso e il middleware che restituiscono una Promise -chiameranno automaticamente `next(value)` quando rifiutano o generano un errore. -Per esempio: +The recommended way to write asynchronous handlers is with `async` functions. +Route handlers and middleware that return a Promise call `next(value)` +automatically when they reject or throw an error, and `async` functions always +return a Promise, so their errors reach Express with no extra work. Per esempio: ```js -app.get('/user/:id', async (req, res, next) => { +app.get('/user/:id', async (req, res) => { const user = await getUserById(req.params.id); res.send(user); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', async (req: Request, res: Response) => { const user = await getUserById(req.params.id); res.send(user); }); @@ -90,49 +65,41 @@ Se passi qualcosa alla funzione `next()` (tranne la stringa `'route'`), Express considera la richiesta corrente come un errore e salterà qualsiasi rimanenti funzioni di routing e middleware senza errori. -Se il callback in una sequenza non fornisce dati, solo errori, è possibile semplificare -questo codice come segue: +### Working with promise chains + +If you build a promise chain instead of using an `async` function, return the +promise from the handler and Express will likewise call `next` automatically +when it rejects: ```js -app.get('/', [ - function (req, res, next) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req, res) { - res.send('OK'); - }, -]); +app.get('/', (req, res) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/', [ - function (req: Request, res: Response, next: NextFunction) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req: Request, res: Response) { - res.send('OK'); - }, -]); +app.get('/', (req: Request, res: Response) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` -Nell'esempio precedente, `next` è fornito come callback per `fs.writeFile`, -che viene chiamato con o senza errori. Se non c'è errore, viene eseguito il secondo gestore -, altrimenti Express cattura ed elabora l'errore. - -È necessario catturare gli errori che si verificano in codice asincrono invocato dai router o -middleware e passarli a Express per l'elaborazione. Per esempio: +If the promise is not returned, Express does not know it exists, and you must +route the error yourself by providing `next` as the final catch handler. +Without it, the rejection would be unhandled and crash the process: ```js app.get('/', (req, res, next) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` @@ -140,31 +107,32 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` -L'esempio precedente utilizza un blocco `try...catch` per catturare errori nel codice asincrono -e passarli a Express. Se il blocco `prova...catch` -fosse omesso, Express non coglierebbe l'errore dal momento che non fa parte del codice di gestione -sincrono. +This works because if a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, `.catch` calls its handler with the error as the first argument, which is exactly the argument `next` expects, so the error reaches Express. -Usa le promesse per evitare l'overhead del blocco `prova...catch` o quando usi le funzioni -che restituiscono le promesse. Per esempio: +### Working with callback APIs + +Errors produced by callback-based APIs, such as those in `node:fs`, are not +thrown and are not part of any promise. The callback receives them as its first +argument, and you must pass them to the `next()` function yourself, where +Express will catch and process them. Per esempio: ```js app.get('/', (req, res, next) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` @@ -172,17 +140,46 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` -Dal momento che le promesse catturano automaticamente entrambi gli errori sincroni e le promesse rifiutate, -puoi semplicemente fornire `next` come il gestore finale di cattura e Express catturerà errori, -perché al gestore della cattura viene dato l'errore come primo argomento. +Se il callback in una sequenza non fornisce dati, solo errori, è possibile semplificare +questo codice come segue: + +```js +app.get('/', [ + function (req, res, next) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req, res) { + res.send('OK'); + }, +]); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', [ + function (req: Request, res: Response, next: NextFunction) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req: Request, res: Response) { + res.send('OK'); + }, +]); +``` + +Nell'esempio precedente, `next` è fornito come callback per `fs.writeFile`, +che viene chiamato con o senza errori. Se non c'è errore, viene eseguito il secondo gestore +, altrimenti Express cattura ed elabora l'errore. Si potrebbe anche utilizzare una catena di gestori per fare affidamento su errore sincrono catching, riducendo il codice asincrono a qualcosa di banale. Per esempio: @@ -219,14 +216,49 @@ app.get('/', [ ]); ``` -L'esempio precedente ha un paio di istruzioni banali dalla chiamata `readFile` -. Se `readFile` causa un errore, allora passa l'errore a Express, altrimenti +The above example contains a couple of trivial statements following the `readFile` +call. Se `readFile` causa un errore, allora passa l'errore a Express, altrimenti torna rapidamente al mondo della gestione sincrona degli errori nel prossimo gestore nella catena. Poi, l'esempio di cui sopra cerca di elaborare i dati. Se questo fallisce, il gestore di errori sincroni lo catturerà. Se avessi fatto questa elaborazione all'interno di il callback `readFile`, l'applicazione potrebbe uscire e i gestori dell'errore Express non sarebbero stati eseguiti. +Finally, for asynchronous code that provides no error-first callback, such as a +timer, catch errors inside the asynchronous code itself and pass them to +Express: + +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', (req: Request, res: Response, next: NextFunction) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +L'esempio precedente utilizza un blocco `try...catch` per catturare errori nel codice asincrono +e passarli a Express. Se il blocco `prova...catch` +fosse omesso, Express non coglierebbe l'errore dal momento che non fa parte del codice di gestione +sincrono. + Qualunque metodo si utilizzi, se si desidera che i gestori di errori Express siano chiamati dentro e l'applicazione per sopravvivere, è necessario assicurarsi che Express riceva l'errore. @@ -424,7 +456,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Anche in questo esempio, `clientErrorHandler` è definito come segue; in questo caso, l'errore viene esplicitamente passato a quello successivo. -Nota che quando _non_ chiama "next" in una funzione di gestione degli errori, sei responsabile della scrittura (e della fine) della risposta. In caso contrario, tali richieste saranno "appese" e non saranno ammissibili per la raccolta rifiuti. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. In caso contrario, tali richieste saranno "appese" e non saranno ammissibili per la raccolta rifiuti. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/it/5x/guide/overriding-express-api.mdx b/src/content/docs/it/5x/guide/overriding-express-api.mdx index c662a827b2..739ec2f203 100644 --- a/src/content/docs/it/5x/guide/overriding-express-api.mdx +++ b/src/content/docs/it/5x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -L'API Express è composta da vari metodi e proprietà su richiesta e oggetti di risposta. Questi sono ereditati dal prototipo. Ci sono due punti di estensione per l'API Express: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. Questi sono ereditati dal prototipo. Ci sono due punti di estensione per l'API Express: 1. I prototipi globali in `express.request` e `express.response`. 2. prototipi specifici per app su `app.request` e `app.response`. diff --git a/src/content/docs/it/5x/guide/routing.mdx b/src/content/docs/it/5x/guide/routing.mdx index 5bac77a010..df3aa1f15b 100644 --- a/src/content/docs/it/5x/guide/routing.mdx +++ b/src/content/docs/it/5x/guide/routing.mdx @@ -13,7 +13,7 @@ per esempio, `app. et()` per gestire le richieste GET e `app.post` per gestire l see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. In altre parole, l'applicazione "ascolta" per le richieste che corrispondono ai percorsi e ai metodi specificati, e quando rileva una corrispondenza, chiama la funzione di callback specificata. +In altre parole, l'applicazione "ascolta" per le richieste che corrispondono ai percorsi e ai metodi specificati, e quando rileva una corrispondenza, chiama la funzione di callback specificata. In altre parole, l'applicazione "ascolta" per le richieste che corrispondono ai percorsi e ai metodi specificati, e quando rileva una corrispondenza, chiama la funzione di callback specificata. Infatti, i metodi di routing possono avere più di una funzione di callback come argomenti. Con funzioni di callback multiple, è importante fornire `next` come argomento alla funzione di callback e poi chiamare `next()` all'interno del corpo della funzione per consegnare il controllo @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express supporta metodi che corrispondono a tutti i metodi di richiesta HTTP: `get`, `post`, e così via. For a full list, see [app.METHOD](/api/application#appmethod). -C'è un metodo di routing speciale, `app.all()`, utilizzato per caricare le funzioni middleware in un percorso per _tutti_ i metodi di richiesta HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +C'è un metodo di routing speciale, `app.all()`, utilizzato per caricare le funzioni middleware in un percorso per _tutti_ i metodi di richiesta HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Percorsi di rotta -Percorsi di percorso, in combinazione con un metodo di richiesta, definire gli endpoint in cui le richieste possono essere fatte. I percorsi del percorso possono essere stringhe o espressioni regolari. +Percorsi di percorso, in combinazione con un metodo di richiesta, definire gli endpoint in cui le richieste possono essere fatte. I percorsi del percorso possono essere stringhe o espressioni regolari. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -153,77 +153,9 @@ app.get('/random.text', (req: Request, res: Response) => { }); ``` -### Wildcards - -I caratteri jolly corrispondono a qualsiasi percorso dopo un prefisso. Devono avere un nome, proprio come i parametri del percorso, e sono catturati come array di segmenti di percorso. - -```js -app.get('/files/*filepath', (req, res) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -Per abbinare anche il percorso di root, avvolgere il wildcard in graffe: - -```js -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req, res) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req: Request, res: Response) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -### Segmenti facoltativi - -Usa le parentesi graffe per definire segmenti opzionali in un percorso percorso. Quando il segmento non è presente, il parametro viene omesso da `req.params`. - -```js -app.get('/:file{.:ext}', (req, res) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/:file{.:ext}', (req: Request, res: Response) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -I caratteri `?`, `+`, `*`, `[]`, e `()` sono riservati e non possono essere usati come caratteri letterali nei percorsi del percorso. Usa `\` per sfuggire se necessario. +The characters `?`, `+`, `*`, `[]`, `()`, and `!` are reserved and cannot be used as literal characters in route paths, and braces are reserved for [optional segments](#optional-segments). Usa `\` per sfuggire se necessario. @@ -259,7 +191,11 @@ app.get(/.*fly$/, (req: Request, res: Response) => { ## Parametri percorso -I parametri del percorso sono denominati segmenti di URL che vengono utilizzati per catturare i valori specificati nella loro posizione nell'URL. I valori catturati sono popolati nell'oggetto `req.params`, con il nome del parametro route specificato nel percorso come loro rispettive chiavi. +I parametri del percorso sono denominati segmenti di URL che vengono utilizzati per catturare i valori specificati nella loro posizione nell'URL. I valori catturati sono popolati nell'oggetto `req.params`, con il nome del parametro route specificato nel percorso come loro rispettive chiavi. They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces. + +### Named parameters + +Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below. ``` Route path: /users/:userId/books/:bookId @@ -293,7 +229,7 @@ app.get('/users/:userId/books/:bookId', sendParams); -Il nome dei parametri del percorso deve essere composto da "caratteri di parola" ([A-Za-z0-9_]). +The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example `:"user-name"`. @@ -313,14 +249,122 @@ req.params: { "genus": "Prunus", "species": "persica" } -I caratteri Regexp non sono supportati nei percorsi del percorso. Usa invece un array di tracciati o espressioni regolari. +Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as `:userId(\d+)`. Use an array of paths or a full regular expression instead. Per maggiori informazioni consultare il [percorso percorso corrispondente alla sintassi](/guide/migrating-5#path-syntax). +### Wildcards + +I caratteri jolly corrispondono a qualsiasi percorso dopo un prefisso. Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string. + +```js +app.get('/files/*filepath', (req, res) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +Per abbinare anche il percorso di root, avvolgere il wildcard in graffe: + +```js +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req, res) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req: Request, res: Response) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +### Segmenti facoltativi + +Usa le parentesi graffe per definire segmenti opzionali in un percorso percorso. Quando il segmento non è presente, il parametro viene omesso da `req.params`. + +```js +app.get('/:file{.:ext}', (req, res) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/:file{.:ext}', (req: Request, res: Response) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters: + +```js +app.get('/user/\{:id}', (req, res) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req, res) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/user/\{:id}', (req: Request, res: Response) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req: Request, res: Response) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +Non confondere la posizione della barra nel percorso della rotta con l'[impostazione `strict routing`](/api/application/#application-settings), che riguarda l'URL della richiesta: controlla se un URL che termina con una barra non richiesta dal percorso della rotta corrisponde comunque. Ad esempio, una richiesta a `/order/` corrisponde per impostazione predefinita alla rotta `/order{/:id}`, ma restituisce un errore 404 quando strict routing è abilitato; la barra finale di `/user/` non è interessata perché la rotta `/user/\{:id}` la richiede. Tutte le richieste commentate negli esempi precedenti si comportano allo stesso modo indipendentemente da questa impostazione.## Route handlersYou can provide multiple callback functions that + ## Gestori del percorso -È possibile fornire più funzioni di callback che si comportano come [middleware](/guide/using-middleware) per gestire una richiesta. L'unica eccezione è che questi callback potrebbero invocare `next('route')` per bypassare i rimanenti callback del percorso. È possibile utilizzare questo meccanismo per imporre condizioni preliminari su un percorso, poi passare il controllo ai percorsi successivi se non c'è motivo di procedere con il percorso corrente. +È possibile fornire più funzioni di callback che si comportano come [middleware](/guide/using-middleware) per gestire una richiesta. L'unica eccezione è che questi callback potrebbero invocare `next('route')` per bypassare i rimanenti callback del percorso. È possibile utilizzare questo meccanismo per imporre condizioni preliminari su un percorso, poi passare il controllo ai percorsi successivi se non c'è motivo di procedere con il percorso corrente.```js +app.get('/user/:id', (req, res, next) => { +if (req.params.i + +```` ```js app.get('/user/:id', (req, res, next) => { @@ -333,7 +377,7 @@ app.get('/user/:id', (req, res, next) => { app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0'); }); -``` +```` ```ts import { type Request, type Response, type NextFunction } from 'express'; @@ -355,15 +399,17 @@ In questo esempio: - `GET /user/5` → gestito dal primo percorso → invia "User 5" - `GET /user/0` → prima rotta chiama `next('route')`, saltando al prossimo percorso corrispondente `/user/:id` -I gestori del percorso possono essere nella forma di una funzione, una serie di funzioni, o combinazioni di entrambi, come mostrato negli esempi seguenti. +I gestori del percorso possono essere nella forma di una funzione, una serie di funzioni, o combinazioni di entrambi, come mostrato negli esempi seguenti.A single callback function can handle a route. For example:```js + +```` -Una singola funzione di callback può gestire un percorso. Per esempio: +Più di una funzione di callback può gestire un percorso (assicurati di specificare l'oggetto `next`). ```js app.get('/example/a', (req, res) => { res.send('Hello from A!'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -373,7 +419,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -Più di una funzione di callback può gestire un percorso (assicurati di specificare l'oggetto `next`). Per esempio: +Una combinazione di funzioni indipendenti e matrici di funzioni può gestire un percorso. Per esempio: ```js app.get( @@ -403,7 +449,7 @@ app.get( ); ``` -Un array di funzioni di callback può gestire un percorso. Per esempio: +Un array di funzioni di callback può gestire un percorso. ```js const cb0 = function (req, res, next) { @@ -497,26 +543,32 @@ app.get( ## Metodi di risposta -I metodi sull'oggetto di risposta (`res`) nella tabella seguente possono inviare una risposta al client e terminare il ciclo di richiesta-risposta. Se nessuno di questi metodi è chiamato da un gestore del percorso, la richiesta del cliente sarà sospesa. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. Se nessuno di questi metodi è chiamato da un gestore del percorso, la richiesta del cliente sarà sospesa.| Method | Description| Method | Description -| Metodo | Descrizione | -| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -| [res.download()](/api/response#resdownload) | Avverte un file da scaricare. | -| [res.end()](/api/response#resend) | Termina il processo di risposta. | -| [res.json()](/api/response#resjson) | Invia una risposta JSON. | -| [res.jsonp()](/api/response#resjsonp) | Invia una risposta JSON con il supporto JSONP. | -| [res.redirect()](/api/response#resredirect) | Reindirizza una richiesta. | -| [res.render()](/api/response#resrender) | Render un modello di visualizzazione. | -| [res.send()](/api/response#ressend) | Invia una risposta di vari tipi. | -| [res.sendFile()](/api/response#ressendfile) | Invia un file come un flusso di otte. | -| [res.sendStatus()](/api/response#ressendstatus) | Imposta il codice di stato della risposta e invia la sua rappresentazione della stringa come corpo della risposta. | +| | | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [res.download()](/api/response#resdownload) | Avverte un file da scaricare. | +| [res.end()](/api/response#resend) | Termina il processo di risposta. | +| [res.json()](/api/response#resjson) | Invia una risposta JSON. | +| [res.jsonp()](/api/response#resjsonp) | Invia una risposta JSON con il supporto JSONP. | +| | Reindirizza una richiesta. | +| [res.render()](/api/response#resrender) | Render un modello di visualizzazione. | +| [res.send()](/api/response#ressend) | Invia una risposta di vari tipi. | +| [res.sendFile()](/api/response#ressendfile) | Invia un file come un flusso di otte. | +| [res.sendStatus()](/api/response#ressendstatus) | Imposta il codice di stato della risposta e invia la sua rappresentazione della stringa come corpo della risposta. \|## app.route()You can create chainable route handlers for a rou | ## app.route() È possibile creare i gestori di rotte per un percorso utilizzando `app.route()`. -Poiché il percorso è specificato in una singola posizione, è utile creare percorsi modulari, così come ridurre la ridondanza e pneumatici. Per ulteriori informazioni sulle rotte, si veda: [Router() documentation](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router).Here is an example of chained route handlers that are defined by us + +Ecco un esempio di router incatenati che sono definiti utilizzando `app.route()`.```js +app +.route('/book') +.get((req, res) => { +res.send('Ge -Ecco un esempio di router incatenati che sono definiti utilizzando `app.route()`. +```` ```js app @@ -530,7 +582,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -550,9 +602,9 @@ app ## express.Router -Usa la classe `express.Router` per creare i gestori modulari e montabili. Un'istanza `Router` è un sistema di routing e middleware completo; per questo motivo è spesso chiamata "mini-app". +Usa la classe `express.Router` per creare i gestori modulari e montabili. Un'istanza `Router` è un sistema di routing e middleware completo; per questo motivo è spesso chiamata "mini-app".The following example creates a router as a module, loads a middlewThe following example creates a router as a module, loads a middlew -L'esempio seguente crea un router come modulo, carica una funzione middleware in esso, definisce alcuni percorsi e monta il modulo del router su un percorso nell'app principale. +L'esempio seguente crea un router come modulo, carica una funzione middleware in esso, definisce alcuni percorsi e monta il modulo del router su un percorso nell'app principale.Create a router file named `birds.js` in the app directory, with thCreate a router file named `birds.js` in the app directory, with th Crea un file router chiamato `birds.js` nella directory delle app, con il seguente contenuto: @@ -645,10 +697,13 @@ import birds from './birds'; app.use('/birds', birds); ``` -L'app sarà ora in grado di gestire le richieste di `/birds` e `/birds/about`, oltre a chiamare la funzione middleware `timeLog` che è specifica per il percorso. +L'app sarà ora in grado di gestire le richieste di `/birds` e `/birds/about`, oltre a chiamare la funzione middleware `timeLog` che è specifica per il percorso.But if the parent route `/birds` has path parameters, it will not b -Ma se il percorso principale `/birds` ha parametri di percorso, non sarà accessibile per impostazione predefinita dai sotto-percorsi. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +Ma se il percorso principale `/birds` ha parametri di percorso, non sarà accessibile per impostazione predefinita dai sotto-percorsi. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter).```js +const router = express.Router({ mergeParams: true }); + +```` ```js const router = express.Router({ mergeParams: true }); -``` +```` diff --git a/src/content/docs/it/5x/guide/using-middleware.mdx b/src/content/docs/it/5x/guide/using-middleware.mdx index 835a17003e..dd12f8b0ad 100644 --- a/src/content/docs/it/5x/guide/using-middleware.mdx +++ b/src/content/docs/it/5x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Scopri come utilizzare middleware nelle applicazioni Express.js, tr import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express è un framework web routing e middleware che ha funzionalità minime proprie: Un'applicazione Express è essenzialmente una serie di chiamate di funzioni middleware. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -Le funzioni _Middleware_ sono funzioni che hanno accesso al [request object](/api#req) (`req`), il [response object](/api#res) (`res`), e la successiva funzione middleware nel ciclo request-response dell'applicazione. La funzione middleware successiva è comunemente indicata da una variabile chiamata `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Le funzioni Middleware possono eseguire le seguenti attività: - Esegue qualsiasi codice. -- Effettuare modifiche alla richiesta e agli oggetti di risposta. +- Modify the request and response objects. - Terminare il ciclo richiesta-risposta. -- Chiama la funzione middleware successiva nello stack. +- Pass control to the next middleware function. -Se la funzione middleware corrente non termina il ciclo richiesta-risposta, deve chiamare `next()` per passare il controllo alla successiva funzione middleware. In caso contrario, la richiesta sarà sospesa. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. In caso contrario, la richiesta sarà sospesa. Un'applicazione Express può utilizzare i seguenti tipi di middleware: @@ -27,14 +32,15 @@ Un'applicazione Express può utilizzare i seguenti tipi di middleware: - [Built-in middleware](#middleware.built-in) - [middleware di terze parti](#middleware.third-party) -È possibile caricare il middleware a livello di applicazione e router con un percorso di montaggio opzionale. -È inoltre possibile caricare una serie di funzioni middleware insieme, che crea una sottopila del sistema middleware in un punto di montaggio. +È possibile caricare il middleware a livello di applicazione e router con un percorso di montaggio opzionale. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Middleware a livello di applicazione -Associa il middleware di livello applicativo ad un'istanza del [app object](/api#app) usando `app.use()` e `app. ETHOD()` funzioni, dove `METHOD` è il metodo HTTP della richiesta che la funzione middleware gestisca (come GET, PUT, o POST) in minuscolo. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -Questo esempio mostra una funzione middleware senza percorso di montaggio. La funzione viene eseguita ogni volta che l'app riceve una richiesta. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -Questo esempio mostra una funzione middleware montata sul percorso `/user/:id`. La funzione viene eseguita per qualsiasi tipo di richiesta HTTP -sul percorso `/user/:id`. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Gestori del percorso + Questo esempio mostra un percorso e la sua funzione di gestore (sistema middleware). La funzione gestisce le richieste GET al percorso `/user/:id`. ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Ecco un esempio di caricamento di una serie di funzioni middleware in un punto di montaggio, con un percorso di montaggio. -Illustra un sub-stack middleware che stampa la richiesta di informazioni per qualsiasi tipo di richiesta HTTP al percorso `/user/:id`. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -I gestori del percorso consentono di definire percorsi multipli per un percorso. L'esempio sottostante definisce due percorsi per le richieste GET al percorso `/user/:id`. Il secondo percorso non causerà alcun problema, ma non verrà mai chiamato perché il primo percorso termina il ciclo richiesta-risposta. +### Multiple route handlers -Questo esempio mostra un sub-stack middleware che gestisce le richieste GET al percorso `/user/:id`. +I gestori del percorso consentono di definire percorsi multipli per un percorso. L'esempio sottostante definisce due percorsi per le richieste GET al percorso `/user/:id`. Il secondo percorso non causerà alcun problema, ma non verrà mai chiamato perché il primo percorso termina il ciclo richiesta-risposta. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -Per saltare il resto delle funzioni middleware da uno stack middleware router, chiama `next('route')` per passare il controllo al percorso successivo. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ Per saltare il resto delle funzioni middleware da uno stack middleware router, c -Questo esempio mostra un sub-stack middleware che gestisce le richieste GET al percorso `/user/:id`. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Middleware può anche essere dichiarato in un array per la riutilizzabilità. +### Reusable middleware arrays -Questo esempio mostra un array con un sub-stack middleware che gestisce le richieste GET al percorso `/user/:id` +Middleware functions can also be grouped into arrays for better reusability. Questo esempio mostra un array con un sub-stack middleware che gestisce le richieste GET al percorso `/user/:id` ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,14 +280,14 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Router-level middleware -Router-level middleware funziona allo stesso modo di application-level middleware, tranne che è legato ad un'istanza di `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); @@ -319,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -369,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -419,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -440,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -Per saltare il resto delle funzioni middleware del router, chiama `next('router')` -per passare il controllo indietro dall'istanza del router. +### Skipping out of a router + +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. -Questo esempio mostra un sub-stack middleware che gestisce le richieste GET al percorso `/user/:id`. +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -512,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## middleware gestione errori - - -La gestione degli errori del middleware richiede sempre _four_ argomenti. È necessario fornire quattro argomenti per -identificarlo come una funzione middleware di gestione degli errori. Anche se non è necessario utilizzare l'oggetto `next` -, è necessario specificarlo per mantenere la firma. Otherwise, the `next` object will be -interpreted as regular middleware and will fail to handle errors. - - - Definire le funzioni middleware per la gestione degli errori allo stesso modo di altre funzioni middleware, tranne con quattro argomenti invece di tre, specificatamente con la firma `(err, req, res, next)`: ```js @@ -539,18 +543,30 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Per maggiori dettagli sulla gestione degli errori middleware, vedere [Gestione degli errori](/guide/error-handling). + -## Middleware incorporato +La gestione degli errori del middleware richiede sempre _four_ argomenti. È necessario fornire quattro argomenti per +identificarlo come una funzione middleware di gestione degli errori. Anche se non è necessario utilizzare l'oggetto `next` +, è necessario specificarlo per mantenere la firma. Otherwise, the `next` object will be +interpreted as regular middleware and will fail to handle errors. + + + + -A partire dalla versione 4.x, Express non dipende più da [Connect](https://github.com/senchalabs/connect). Le funzioni middleware -che erano state precedentemente incluse con Express sono ora in moduli separati; vedi [la lista delle funzioni middleware](https://github.com/senchalabs/connect#middleware). +For more information, see the [Error handling](/guide/error-handling) guide. + + + +## Middleware incorporato Express ha le seguenti funzioni middleware integrate: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. -- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTA: Disponibile con Express 4.16.0+** -- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTA: Disponibile con Express 4.16.0+** +- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. +- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. ## middleware di terze parti @@ -591,4 +607,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Per una lista parziale delle funzioni middleware di terze parti che sono comunemente usate con Express, vedere [middleware di terze parti](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/it/5x/guide/using-template-engines.mdx b/src/content/docs/it/5x/guide/using-template-engines.mdx index b871c2ebf6..fda726dba6 100644 --- a/src/content/docs/it/5x/guide/using-template-engines.mdx +++ b/src/content/docs/it/5x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Utilizzo di modelli di motori con Express -description: Scopri come integrare e utilizzare modelli di motori come Pug, Manubri ed EJS con Express.js per rendere le pagine HTML dinamiche in modo efficiente. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ Un motore _modello_ ti permette di utilizzare file di template statici nella tua in un modello di file con valori reali, e trasforma il modello in un file HTML inviato al client. Questo approccio rende più facile progettare una pagina HTML. -Il [generatore di applicazioni Express](/starter/generator) utilizza [Pug](https://pugjs.org/api/getting-started.html) come predefinito, ma supporta anche [Handlebars](https://www.npmjs.com/package/handlebars), e [EJS](https://www.npmjs.com/package/ejs), tra gli altri. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, la directory dove si trovano i file del modello. Eg: `app.set('views', './views')`. Questo valore predefinito è la directory `views` nella directory radice dell'applicazione. - `view engine`, il modello motore da usare. Ad esempio, per usare il motore modello Pug: `app.set('view engine', 'pug')`. -Quindi installare il corrispondente pacchetto npm del motore del modello; per esempio per installare Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ che `res.render()` chiama per rendere il codice del modello. Alcuni modelli di motori non seguono questa convenzione. La libreria [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) segue questa convenzione mappando tutti i popolari motori di template Node.js, e quindi funziona perfettamente all'interno di Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/it/5x/guide/writing-middleware.mdx b/src/content/docs/it/5x/guide/writing-middleware.mdx index b40c8f197e..41ad242959 100644 --- a/src/content/docs/it/5x/guide/writing-middleware.mdx +++ b/src/content/docs/it/5x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Scopri come scrivere funzioni middleware personalizzate per le appl --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Le funzioni _Middleware_ sono funzioni che hanno accesso al [request object](/api#req) (`req`), il [response object](/api#res) (`res`), e la funzione `next` nel ciclo request-response dell'applicazione. La funzione `next` è una funzione nel router Express che, quando invocato, esegue il middleware con successo al middleware corrente. @@ -170,8 +171,8 @@ La funzione middleware `myLogger` semplicemente stampa un messaggio, poi passa l ### Richiesta funzione Middleware -Successivamente, creeremo una funzione middleware chiamata "requestTime" e aggiungeremo una proprietà chiamata `requestTime` -all'oggetto richiesta. +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -391,9 +392,13 @@ come un errore e salterà tutte le rimanenti funzioni di routing e middleware -Poiché hai accesso all'oggetto richiesta, all'oggetto risposta, alla funzione middleware successiva nello stack, e all'intero Node. s API, le possibilità con funzioni middleware sono infinite. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Per ulteriori informazioni su middleware Express, consultare: [Using Express middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Middleware configurabile diff --git a/src/content/docs/it/5x/starter/basic-routing.mdx b/src/content/docs/it/5x/starter/basic-routing.mdx index 03fb7c1f28..c80f433a3b 100644 --- a/src/content/docs/it/5x/starter/basic-routing.mdx +++ b/src/content/docs/it/5x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Impara i fondamenti del routing nelle applicazioni Express.js, tra --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ si riferisce alla determinazione di come un'applicazione risponde a una richiesta di client a un determinato endpoint, che è un URI (o percorso) e un metodo di richiesta HTTP specifico (GET, POST, e così via). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -Per maggiori dettagli sul routing, consulta la [guida di routing](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/it/5x/starter/faq.mdx b/src/content/docs/it/5x/starter/faq.mdx index 055cd570ee..b8d16970de 100644 --- a/src/content/docs/it/5x/starter/faq.mdx +++ b/src/content/docs/it/5x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Trova le risposte alle domande più frequenti su Express.js, inclusi argomenti sulla struttura delle applicazioni, modelli, autenticazione, modelli motori, gestione degli errori e altro ancora. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## Come dovrei strutturare la mia applicazione? Non esiste una risposta definitiva a questa domanda. La risposta dipende da @@ -42,7 +44,11 @@ Per normalizzare i modelli di interfacce motore e caching, vedere il progetto [consolidate.js](https://github.com/visionmedia/consolidate.js) per il supporto. Motori modello non elencati potrebbero ancora supportare la firma Express. -Per ulteriori informazioni, vedere [Utilizzo di modelli di motori con Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## Come posso gestire 404 risposte? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Per ulteriori informazioni, vedere [Gestione degli errori](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Come faccio a rendere semplice HTML? diff --git a/src/content/docs/it/5x/starter/installing.mdx b/src/content/docs/it/5x/starter/installing.mdx index d2ef471b7e..f8e2612e43 100644 --- a/src/content/docs/it/5x/starter/installing.mdx +++ b/src/content/docs/it/5x/starter/installing.mdx @@ -70,7 +70,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/it/5x/starter/static-files.mdx b/src/content/docs/it/5x/starter/static-files.mdx index 041dce63ce..a682560cf4 100644 --- a/src/content/docs/it/5x/starter/static-files.mdx +++ b/src/content/docs/it/5x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Comprendi come servire file statici come immagini, CSS e JavaScript --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Per servire file statici come immagini, file CSS e file JavaScript, utilizzare la funzione middleware integrata `express.static` in Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + Per maggiori dettagli sulla funzione `serve-static` e sulle sue opzioni, vedere [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/ja/4x/guide/debugging.mdx b/src/content/docs/ja/4x/guide/debugging.mdx index 158b013dd9..d9be94f483 100644 --- a/src/content/docs/ja/4x/guide/debugging.mdx +++ b/src/content/docs/ja/4x/guide/debugging.mdx @@ -4,6 +4,7 @@ description: DEBUG環境変数を設定して、Express.jsアプリケーショ --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; Express で使用されるすべての内部ログを表示するには、アプリを起動するときに `DEBUG` 環境変数を `express:*` に設定します。 @@ -86,22 +87,119 @@ $ DEBUG=express:* node ./bin/www ルータの実装からのみログを見るには、`DEBUG`の値を`express:router`に設定します。 同様に、アプリケーションの実装からのログのみを見るには、`DEBUG`の値を`express:application`などに設定します。 同様に、アプリケーションの実装からのログのみを見るには、`DEBUG`の値を`express:application`などに設定します。 -## `express` で生成されたアプリケーション +## Using `debug` in your own code -`express`コマンドによって生成されたアプリケーションは、`debug`モジュールを使用し、デバッグ名前空間はアプリケーションの名前をスコープします。 +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: -例えば、 `$ express sample-app` を使用してアプリを生成した場合、次のコマンドでデバッグ文を有効にできます。 + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; + +const debug = debugModule('myapp:server'); +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` カンマ区切りの名前のリストを割り当てることで、複数のデバッグ名前空間を指定できます: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,express:router node index.js +``` + +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*" } +} ``` +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## 高度なオプション Node.js を介して実行する場合、デバッグログの動作を変更するいくつかの環境変数を設定できます。 diff --git a/src/content/docs/ja/4x/guide/error-handling.mdx b/src/content/docs/ja/4x/guide/error-handling.mdx index 2a920ea11a..4943890167 100644 --- a/src/content/docs/ja/4x/guide/error-handling.mdx +++ b/src/content/docs/ja/4x/guide/error-handling.mdx @@ -64,15 +64,16 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Define error-handling middleware functions in the same way as other middleware functions, -except error-handling functions have four arguments instead of three: -`(err, req, res, next)`. -例: +Errors from rejected promises are not passed to `next` automatically, and this includes `async` functions: if an `async` route handler throws or awaits a rejected promise, the rejection is unhandled, which crashes the process on current Node.js versions. You must catch the error yourself and pass it to Express: ```js app.get('/user/:id', async (req, res, next) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` @@ -80,14 +81,22 @@ app.get('/user/:id', async (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` -If `getUserById` throws an error or rejects, `next` will be called with either -the thrown error or the rejected value. 拒否された値が指定されていない場合、 `next` -はExpress ルータが提供するデフォルトの Error オブジェクトで呼び出されます。 + + +Consider [updating to Express 5](/guide/migrating-5), where route handlers and middleware that +return a Promise call `next(value)` automatically when they reject or throw an error, making the +`try...catch` above unnecessary. + + `next()`関数に何かを渡した場合(`'route'`を除く)。 Expressは現在のリクエストをエラーとみなし、 @@ -184,9 +193,7 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Since promises automatically catch both synchronous errors and rejected promises, -you can simply provide `next` as the final catch handler and Express will catch errors, -because the catch handler is given the error as the first argument. +If a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, passing `next` as the handler is enough: `.catch` calls it with the error as its first argument, which is exactly the argument `next` expects, so the error reaches Express. また、非同期コードを些細なものに減らすことで、同期エラー のキャッチに依存するハンドラのチェーンを使用することもできます。 例: 例: @@ -223,7 +230,7 @@ app.get('/', [ ]); ``` -The above example has a couple of trivial statements from the `readFile` +The above example contains a couple of trivial statements following the `readFile` call. 上の例では、`readFile` 呼び出しからいくつかの些細な文があります。 `readFile` でエラーが発生した場合、エラーは Express に渡されます。 それ以外の場合は、 チェーン内の次のハンドラ @@ -432,7 +439,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) この例でも、`clientErrorHandler`は以下のように定義されています。この場合、エラーは明示的に次のエラーに渡されます。 -Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/ja/4x/guide/overriding-express-api.mdx b/src/content/docs/ja/4x/guide/overriding-express-api.mdx index e80a7c127a..01323166be 100644 --- a/src/content/docs/ja/4x/guide/overriding-express-api.mdx +++ b/src/content/docs/ja/4x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -Express API は、リクエストオブジェクトとレスポンスオブジェクトのさまざまなメソッドとプロパティで構成されています。 これらはプロトタイプによって継承されます。 Express API には 2 つの拡張ポイントがあります。 These are inherited by prototype. There are two extension points for the Express API: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. These are inherited by prototype. There are two extension points for the Express API: 1. `express.request` と `express.response` のグローバルプロトタイプ。 2. `app.request`と`app.response`でアプリ固有のプロトタイプ。 diff --git a/src/content/docs/ja/4x/guide/routing.mdx b/src/content/docs/ja/4x/guide/routing.mdx index 754360cdbb..6e726e06b8 100644 --- a/src/content/docs/ja/4x/guide/routing.mdx +++ b/src/content/docs/ja/4x/guide/routing.mdx @@ -14,7 +14,7 @@ HTTPメソッドに対応するExpress `app` オブジェクトのメソッド see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. 言い換えれば、アプリケーションは指定されたルートとメソッドに一致するリクエストを「リッスン」します。 マッチを検出すると、指定されたコールバック関数を呼び出します。 +言い換えれば、アプリケーションは指定されたルートとメソッドに一致するリクエストを「リッスン」します。 マッチを検出すると、指定されたコールバック関数を呼び出します。 These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. 実際、ルーティングメソッドは引数として複数のコールバック関数を持つことができます。 複数のコールバック関数を使用。 コールバック関数に `next` を引数として渡し、関数の本体内で `next()` を呼び出して、次のコールバックに @@ -88,11 +88,13 @@ app.post('/', (req: Request, res: Response) => { }); ``` -Expressは、すべてのHTTPリクエストメソッドに対応するメソッドをサポートしています: `get`、`post`など。 -完全なリストについては、 [app.METHOD](/api/application#appmethodpath-callback--callback-) を参照してください。 -For a full list, see [app.METHOD](/api/application#appmethod). +HTTPメソッドに対応するExpress `app` オブジェクトのメソッドを使用してルーティングを定義します。 +のように、`app。 POST リクエストを処理する GET リクエストと `app.post\` を処理します。 For a full list, +see [app.METHOD](/api/application#appmethod). +You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to +specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -特別なルーティングメソッド`app.all()`があり、\_all_HTTPリクエストメソッドのパスにミドルウェア関数をロードするために使用されます。 例えば、`GET`を使用しているかどうかに関わらず、ルート`"/secret"へのリクエストに対して以下のハンドラが実行されます。 `POST`、`PUT`、`DELETE\`、または[http module](https://nodejs.org/api/http.html#http_http_methods)でサポートされている他のHTTPリクエストメソッド。 For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +特別なルーティングメソッド`app.all()`があり、\_all_HTTPリクエストメソッドのパスにミドルウェア関数をロードするために使用されます。 例えば、`GET`を使用しているかどうかに関わらず、ルート`"/secret"へのリクエストに対して以下のハンドラが実行されます。 `POST`、`PUT`、`DELETE\`、または[http module](https://nodejs.org/api/http.html#http_http_methods)でサポートされている他のHTTPリクエストメソッド。 For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -112,7 +114,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## ルートパス -ルートパスはリクエストメソッドと組み合わせて、リクエストを作成できるエンドポイントを定義します。 ルートパスは文字列または正規表現にすることができます。 Route paths can be strings, string patterns, or regular expressions. +ルートパスはリクエストメソッドと組み合わせて、リクエストを作成できるエンドポイントを定義します。 ルートパスは文字列または正規表現にすることができます。 Route paths can be strings or regular expressions. Route paths can be strings, string patterns, or regular expressions. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -240,6 +242,26 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => { }); ``` +A wildcard (`*`) on its own matches anything at its position, including entire subpaths. For example, this route path will match `/file/style.css` as well as `/file/javascripts/jquery.js`. Wildcards are unnamed, so the matched value is available as `req.params[0]` instead of a named parameter. + +```js +app.get('/file/*', (req, res) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/file/*', (req: Request, res: Response) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + ### 正規表現に基づく経路パス @@ -353,9 +375,17 @@ req.params: {"userId": "42"} The [`*`](https://github.com/expressjs/express/issues/2495) character in regular expressions is not interpreted in the usual way. 回避策として、`*` の代わりに `{0,}` を使用します。 +Unlike named route parameters, wildcard (`*`) matches in [string patterns](#route-paths-based-on-string-patterns) and capture groups in regular expressions are unnamed: their values are available by position, as `req.params[0]`, `req.params[1]`, and so on. + +``` +Route path: /file/*/size/* +Request URL: http://localhost:3000/file/javascripts/jquery.js/size/large +req.params: { "0": "javascripts/jquery.js", "1": "large" } +``` + ## Route handlers -リクエストを処理するために、 [middleware](/guide/using-middleware) のように動作する複数のコールバック関数を提供できます。 唯一の例外は、これらのコールバックが `next('route')` を呼び出して、残りのルートコールバックをバイパスすることです。 このメカニズムを使用して、ルート上に事前条件を設定できます。 次に現在のルートを進める理由がなければ次のルートに制御を渡す。 The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route. +リクエストを処理するために、 [middleware](/guide/using-middleware) のように動作する複数のコールバック関数を提供できます。 唯一の例外は、これらのコールバックが `next('route')` を呼び出して、残りのルートコールバックをバイパスすることです。 このメカニズムを使用して、ルート上に事前条件を設定できます。 次に現在のルートを進める理由がなければ次のルートに制御を渡す。 The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route. ```js app.get('/user/:id', (req, res, next) => { @@ -408,7 +438,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -複数のコールバック関数がルートを処理できます (`next` オブジェクトを指定してください)。 例: 例: +複数のコールバック関数がルートを処理できます (`next` オブジェクトを指定してください)。 例: 例: 例: ```js app.get( @@ -478,7 +508,7 @@ const cb2 = function (req: Request, res: Response) { app.get('/example/c', [cb0, cb1, cb2]); ``` -独立した関数と関数の配列の組み合わせは、ルートを処理することができます。 例: 例: +独立した関数と関数の配列の組み合わせは、ルートを処理することができます。 例: 例: 例: ```js const cb0 = function (req, res, next) { @@ -532,25 +562,26 @@ app.get( ## レスポンスメソッド -次の表のレスポンスオブジェクト (`res`) のメソッドは、クライアントにレスポンスを送信し、リクエスト応答のサイクルを終了することができます。 これらのメソッドのいずれもルートハンドラから呼び出されない場合、クライアントリクエストはハングしたままになります。 If none of these methods are called from a route handler, the client request will be left hanging. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging. -| 方法 | 説明 | -| ----------------------------------------------- | ---------------------------------------------------------------------------------- | -| [res.download()](/api/response#resdownload) | ダウンロードするファイルを指示します。 | -| [res.end()](/api/response#resend) | 応答プロセスを終了します。 | -| [res.json()](/api/response#resjson) | JSON 応答を送信します。 | -| [res.jsonp()](/api/response#resjsonp) | JSONP サポートを使用して JSON 応答を送信します。 | -| [res.redirect()](/api/response#resredirect) | Redirect a request. | -| [res.render()](/api/response#resrender) | ビューテンプレートをレンダリングします。 | -| [res.send()](/api/response#ressend) | さまざまなタイプの応答を送信します。 | -| [res.sendFile()](/api/response#ressendfile) | ファイルをオクテットストリームとして送信する。 | -| [res.sendStatus()](/api/response#ressendstatus) | レスポンスステータスコードを設定し、文字列表現をレスポンスボディとして送信します。 | +| 方法 | 説明 | +| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/api/response#resdownload) | ダウンロードするファイルを指示します。 | +| [res.end()](/api/response#resend) | 応答プロセスを終了します。 | +| [res.json()](/api/response#resjson) | JSON 応答を送信します。 | +| [res.jsonp()](/api/response#resjsonp) | JSONP サポートを使用して JSON 応答を送信します。 | +| [res.redirect()](/api/response#resredirect) | Redirect a request. | +| [res.render()](/api/response#resrender) | ビューテンプレートをレンダリングします。 | +| [res.send()](/api/response#ressend) | さまざまなタイプの応答を送信します。 | +| [res.sendFile()](/api/response#ressendfile) | ファイルをオクテットストリームとして送信する。 | +| [res.sendStatus()](/api/response#ressendstatus) | レスポンスステータスコードを設定し、文字列表現をレスポンスボディとして送信します。 \|## app.route()You can create chainable route handlers for a rou | ## app.route() `app.route()` を使用すると、ルートパスに対してチェーン可能なルートハンドラを作成できます。 パスは単一の場所で指定されているため、モジュラールートを作成することは、冗長性とタイプミスを削減するのに役立ちます。 ルートの詳細については、以下を参照してください: [Router() documentation](/api/router)。 -Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router). 以下は、`app.route()`を使用して定義されたルートハンドラの例です。 @@ -586,9 +617,9 @@ app ## express.Router -Use the `express.Router` class to create modular, mountable route handlers. `express.Router` クラスを使用して、モジュール化されたマウント可能なルートハンドラを作成します。 `Router`インスタンスは完全なミドルウェアとルーティングシステムです。そのため、しばしば「ミニアプリ」と呼ばれます。 +Use the `express.Router` class to create modular, mountable route handlers. `express.Router` クラスを使用して、モジュール化されたマウント可能なルートハンドラを作成します。 `Router`インスタンスは完全なミドルウェアとルーティングシステムです。そのため、しばしば「ミニアプリ」と呼ばれます。The following example creates a router as a module, loads a middlew -次の例では、ルータをモジュールとして作成し、ミドルウェア関数をロードします。 いくつかのルートを定義し、メインアプリのパスにルータモジュールをマウントします。 +次の例では、ルータをモジュールとして作成し、ミドルウェア関数をロードします。 いくつかのルートを定義し、メインアプリのパスにルータモジュールをマウントします。Create a router file named `birds.js` in the app directory, with th appディレクトリに`birds.js`という名前のルーターファイルを作成します。以下の内容を使用します。 @@ -683,7 +714,7 @@ app.use('/birds', birds); アプリは `/birds` と `/birds/about` へのリクエストを処理できるようになりました。 同様に、ルート固有の「timeLog」ミドルウェア関数を呼び出します。 -ただし、親ルート `/birds` にパスパラメータがある場合、サブルートからデフォルトではアクセスできません。 アクセス可能にするには、 `mergeParams` オプションを Router コンストラクタ [reference](/api/application#appusepath-callback--callback) に渡す必要があります。 To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +ただし、親ルート `/birds` にパスパラメータがある場合、サブルートからデフォルトではアクセスできません。 アクセス可能にするには、 `mergeParams` オプションを Router コンストラクタ [reference](/api/application#appusepath-callback--callback) に渡す必要があります。 ただし、親ルート `/birds` にパスパラメータがある場合、サブルートからデフォルトではアクセスできません。 アクセス可能にするには、 `mergeParams` オプションを Router コンストラクタ [reference](/api/application#appusepath-callback--callback) に渡す必要があります。 To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter). ```js const router = express.Router({ mergeParams: true }); diff --git a/src/content/docs/ja/4x/guide/using-middleware.mdx b/src/content/docs/ja/4x/guide/using-middleware.mdx index 6d6c4e69c6..fb808dcd8e 100644 --- a/src/content/docs/ja/4x/guide/using-middleware.mdx +++ b/src/content/docs/ja/4x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Express.jsアプリケーションでミドルウェアを使用す import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express はルーティングおよびミドルウェアの Web フレームワークで、独自の最小限の機能を持っています。Express アプリケーションは、基本的にはミドルウェア関数の一連の呼び出しです。 +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -_Middleware_ 関数は、[request object](/api#req) (`req`) にアクセスできる関数です。 [response object](/api#res) (`res`) と、アプリケーションのリクエストレスポンスサイクルの次のミドルウェア関数。 次のミドルウェア関数は通常`next`という名前の変数で表されます。 次のミドルウェア関数は通常`next`という名前の変数で表されます。 +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` ミドルウェア機能は以下のタスクを実行できます。 - 任意のコードを実行します。 -- リクエストとレスポンスオブジェクトに変更を加えます。 +- Modify the request and response objects. - リクエストレスポンスサイクルを終了します。 -- スタック内の次のミドルウェア関数を呼び出します。 +- Pass control to the next middleware function. -現在のミドルウェア関数がリクエスト応答サイクルを終了しない場合は、次のミドルウェア関数に制御を渡すために `next()` を呼び出す必要があります。 そうでなければ、リクエストはハングアップのままになります。 そうでなければ、リクエストはハングアップのままになります。 +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. そうでなければ、リクエストはハングアップのままになります。 Express アプリケーションでは、次のタイプのミドルウェアを使用できます。 @@ -28,14 +33,15 @@ Express アプリケーションでは、次のタイプのミドルウェアを - [Third-party middleware](#middleware.third-party) アプリケーションレベルおよびルーターレベルのミドルウェアは、任意のマウントパスでロードできます。 -また、一連のミドルウェア関数を一緒にロードして、マウントポイントでミドルウェアシステムのサブスタックを作成することもできます。 -また、一連のミドルウェア関数を一緒にロードして、マウントポイントでミドルウェアシステムのサブスタックを作成することもできます。 +また、一連のミドルウェア関数を一緒にロードして、マウントポイントでミドルウェアシステムのサブスタックを作成することもできます。 Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## アプリケーションレベルのミドルウェア -`app.use()` と `app()` を使用して、アプリケーションレベルのミドルウェアを [app object](/api#app) のインスタンスにバインドします。 ETHOD()関数。`METHOD`はミドルウェア関数が小文字で処理するHTTPメソッドです(GET、PUT、POSTなど)。 +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -この例では、マウントパスのないミドルウェア関数を示します。 この関数はアプリがリクエストを受け取るたびに実行されます。 この関数はアプリがリクエストを受け取るたびに実行されます。 +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -69,8 +75,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -This example shows a middleware function mounted on the `/user/:id` path. この例では、`/user/:id` パスにマウントされたミドルウェア関数を示します。 関数は `/user/:id` パス上の任意のタイプの -HTTP リクエストに対して実行されます。 +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -88,24 +95,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Route handlers + This example shows a route and its handler function (middleware system). この例ではルートとハンドラ関数(ミドルウェアシステム)を示します。 関数は`/user/:id`パスへのGETリクエストを処理します。 ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Here is an example of loading a series of middleware functions at a mount point, with a mount path. -It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the `/user/:id` path. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -137,9 +147,9 @@ app.use( ); ``` -Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. +### Multiple route handlers -この例では、`/user/:id`パスへのGETリクエストを処理するミドルウェアサブスタックを示します。 +Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. ```js app.get( @@ -148,13 +158,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -168,18 +178,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -他のミドルウェア関数をルータのミドルウェアスタックからスキップするには、次のルートに制御を渡すために `next('route')` を呼び出します。 +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -188,7 +200,7 @@ app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { -この例では、`/user/:id`パスへのGETリクエストを処理するミドルウェアサブスタックを示します。 +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -199,14 +211,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -222,21 +234,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -ミドルウェアは、再利用可能な配列で宣言することもできます。 +### Reusable middleware arrays -この例では、`/user/:id`パスへのGETリクエストを処理するミドルウェアサブスタックを持つ配列を示しています。 +Middleware functions can also be grouped into arrays for better reusability. この例では、`/user/:id`パスへのGETリクエストを処理するミドルウェアサブスタックを持つ配列を示しています。 ```js function logOriginalUrl(req, res, next) { @@ -250,7 +262,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -269,19 +281,25 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## ルーターレベルのミドルウェア -ルータレベルのミドルウェアは、`express.Router()`のインスタンスにバインドされている場合を除き、アプリケーションレベルのミドルウェアと同じ方法で動作します。 +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); ``` +```ts +import express from 'express'; + +const router = express.Router(); +``` + `router.use()`と`router.METHOD()`関数を使ってルーターレベルのミドルウェアをロードします。 次のコード例は、ルーターレベルのミドルウェアを使用して、アプリケーションレベルのミドルウェアに対して上記のミドルウェアシステムを複製します。 @@ -314,19 +332,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -364,19 +382,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -414,19 +432,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -435,10 +453,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -ルーターのミドルウェア関数の残りをスキップするには、`next('router')` -を呼び出してルーターインスタンスからコントロールを渡します。 +### Skipping out of a router -この例では、`/user/:id`パスへのGETリクエストを処理するミドルウェアサブスタックを示します。 +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. + +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -507,15 +526,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## エラー処理のミドルウェア - - -Error-handling middleware always takes _four_ arguments. You must provide four arguments to -identify it as an error-handling middleware function. Even if you don't need to use the `next` -object, you must specify it to maintain the signature. Otherwise, the `next` object will be -interpreted as regular middleware and will fail to handle errors. - - - 他のミドルウェア関数と同じ方法でエラー処理ミドルウェア関数を定義します 3 つの代わりに 4 つの引数を指定する場合を除き、特に \`(err, req, res, next) というシグネチャを使用します。 ```js @@ -534,7 +544,20 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -エラー処理ミドルウェアの詳細については、[Error handling](/guide/error-handling)を参照してください。 + + +Error-handling middleware always takes _four_ arguments. You must provide four arguments to +identify it as an error-handling middleware function. Even if you don't need to use the `next` +object, you must specify it to maintain the signature. Otherwise, the `next` object will be +interpreted as regular middleware and will fail to handle errors. + + + + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## 組み込みのミドルウェア @@ -545,6 +568,8 @@ Express には次のミドルウェア関数が組み込まれています。 - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. - [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. **NOTE: Available with Express 4.17.0+** +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. **NOTE: Available with Express 4.17.0+** - [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** ## Third-party middleware @@ -586,4 +611,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Expressで一般的に使用されるサードパーティミドルウェア関数の部分的なリストについては、[サードパーティミドルウェア](/resources/middleware)を参照してください。 + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/ja/4x/guide/using-template-engines.mdx b/src/content/docs/ja/4x/guide/using-template-engines.mdx index afa905188e..488eceec20 100644 --- a/src/content/docs/ja/4x/guide/using-template-engines.mdx +++ b/src/content/docs/ja/4x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Express でテンプレートエンジンを使用する -description: Pug、Handlebars、EJSなどのテンプレートエンジンをExpress.jsで統合して使用し、動的なHTMLページを効率的にレンダリングする方法をご覧ください。 +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -11,15 +11,15 @@ _template engine_ を使用すると、アプリケーションで静的なテ このアプローチにより、HTML ページのデザインが容易になります。 このアプローチにより、HTML ページのデザインが容易になります。 -The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it also supports [Handlebars](https://www.npmjs.com/package/handlebars), and [EJS](https://www.npmjs.com/package/ejs), among others. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views` テンプレートファイルがあるディレクトリ。 例: `app.set('views', './views')` 。 デフォルトはアプリケーションのルートディレクトリにある `views` ディレクトリです。 - `viewengine` を使用するテンプレートエンジン。 `viewengine` を使用するテンプレートエンジン。 たとえば、Pugテンプレートエンジンを使用するには、`app.set('view engine', 'pug')`を使います。 -次に、対応するテンプレートエンジン npm パッケージをインストールします。例えば、Pug をインストールする場合: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -29,6 +29,7 @@ Pug のような Express 準拠のテンプレートエンジンは、 `__expres 一部のテンプレートエンジンはこの規約に従っていません。 一部のテンプレートエンジンはこの規約に従っていません。 [@ladjs/integrate](https://www.npmjs.com/package/@ladjs/consolidate) ライブラリは、一般的な Node.js テンプレートエンジンのすべてをマッピングすることによって、この規則に従っており、したがって、Express 内でシームレスに動作します。 +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/ja/4x/guide/writing-middleware.mdx b/src/content/docs/ja/4x/guide/writing-middleware.mdx index cfa2434ae5..56e11ded04 100644 --- a/src/content/docs/ja/4x/guide/writing-middleware.mdx +++ b/src/content/docs/ja/4x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Express.jsアプリケーション用にカスタムミドルウェ --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Middleware_ 関数は、[request object](/api#req) (`req`) にアクセスできる関数です。 [response object](/api#res) (`res`)とアプリケーションのリクエストレスポンスサイクルの中の `next` 関数。 `next` 関数はExpressルータ内の関数で、呼び出されたときに現在のミドルウェアを継承してミドルウェアを実行します。 `next` 関数はExpressルータ内の関数で、呼び出されたときに現在のミドルウェアを継承してミドルウェアを実行します。 @@ -202,8 +203,8 @@ app.listen(3000); ### ミドルウェア関数requestTime -次に、"requestTime" というミドルウェア関数を作成し、リクエストオブジェクトに `requestTime` -というプロパティを追加します。 +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -427,9 +428,13 @@ functions. -リクエストオブジェクト、レスポンスオブジェクト、スタック内の次のミドルウェア関数、そしてノード全体にアクセスできるためです。 s API、ミドルウェア関数の可能性は無限大です。 +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Express ミドルウェアの詳細については、[Express ミドルウェアを使用する](/guide/using-middleware)を参照してください。 + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## 設定可能なミドルウェア diff --git a/src/content/docs/ja/4x/starter/basic-routing.mdx b/src/content/docs/ja/4x/starter/basic-routing.mdx index be14ee4b41..7ad621db6f 100644 --- a/src/content/docs/ja/4x/starter/basic-routing.mdx +++ b/src/content/docs/ja/4x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Express.jsアプリケーションでルーティングの基礎を --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ は、アプリケーションが特定のエンドポイントに対してどのように応答するかを決定することを指します。 これはURI(またはパス)と特定のHTTPリクエストメソッド(GET、POSTなど)です。 @@ -97,4 +98,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -For more details about routing, see the [routing guide](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/ja/4x/starter/faq.mdx b/src/content/docs/ja/4x/starter/faq.mdx index b879933149..5ea721ac5a 100644 --- a/src/content/docs/ja/4x/starter/faq.mdx +++ b/src/content/docs/ja/4x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Express.jsについてよく寄せられる質問の答えを見つけましょう。その中には、アプリケーション構造、モデル、認証、テンプレートエンジン、エラー処理などのトピックが含まれます。 --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## アプリケーションを構成するにはどうすればいいですか? There is no definitive answer to this question. この質問には決定的な答えはありません。 The answer depends @@ -49,7 +51,11 @@ To normalize template engine interfaces and caching, see the [consolidate.js](https://github.com/visionmedia/consolidate.js) project for support. Unlisted template engines might still support the Express signature. -詳しくは、[Expressでテンプレートエンジンを使用する](/guide/using-template-engines)を参照してください。 + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## 404応答はどのように処理すればいいですか? @@ -100,7 +106,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -詳細については、[Error handling](/guide/error-handling)を参照してください。 + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## プレーンHTMLをレンダリングするにはどうすればいいですか? diff --git a/src/content/docs/ja/4x/starter/installing.mdx b/src/content/docs/ja/4x/starter/installing.mdx index 6ca17fe378..13b1e75d08 100644 --- a/src/content/docs/ja/4x/starter/installing.mdx +++ b/src/content/docs/ja/4x/starter/installing.mdx @@ -79,7 +79,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/ja/4x/starter/static-files.mdx b/src/content/docs/ja/4x/starter/static-files.mdx index 9ce3278bac..057af002f1 100644 --- a/src/content/docs/ja/4x/starter/static-files.mdx +++ b/src/content/docs/ja/4x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: 組み込みの 'static' ミドルウェアを使用して、Expres --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; 画像、CSSファイル、JavaScriptファイルなどの静的ファイルを提供するには、Express で組み込まれているミドルウェア関数「express.static」を使用します。 @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + `serve-static` 関数とそのオプションの詳細については、 [serve-static](/resources/middleware/serve-static) を参照してください。 + + diff --git a/src/content/docs/ja/5x/guide/debugging.mdx b/src/content/docs/ja/5x/guide/debugging.mdx index 158b013dd9..88ab6955e9 100644 --- a/src/content/docs/ja/5x/guide/debugging.mdx +++ b/src/content/docs/ja/5x/guide/debugging.mdx @@ -4,104 +4,218 @@ description: DEBUG環境変数を設定して、Express.jsアプリケーショ --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -Express で使用されるすべての内部ログを表示するには、アプリを起動するときに `DEBUG` 環境変数を -`express:*` に設定します。 +To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*,router,router:*` when launching your app. Routing is handled by the separate [router](https://github.com/pillarjs/router) package, so its logs live under the `router` namespace and are not included in `express:*`. ```bash -$ DEBUG=express:* node index.js +$ DEBUG=express:*,router,router:* node index.js ``` Windows では、対応するコマンドを使用します。 ```bash -> $env:DEBUG = "express:*"; node index.js +> $env:DEBUG = "express:*,router,router:*"; node index.js ``` -[express generator](/starter/generator) で生成されたデフォルトのアプリでこのコマンドを実行すると、以下の出力が出力されます。 +Running this command on a small app with a JSON body parser and a mounted router prints the following output: + +```cjs title="index.cjs" +const express = require('express'); + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` + +```mjs title="index.mjs" +import express from 'express'; + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` ```bash -$ DEBUG=express:* node ./bin/www - express:router:route new / +0ms - express:router:layer new / +1ms - express:router:route get / +1ms - express:router:layer new / +0ms - express:router:route new / +1ms - express:router:layer new / +0ms - express:router:route get / +0ms - express:router:layer new / +0ms - express:application compile etag weak +1ms - express:application compile query parser extended +0ms - express:application compile trust proxy false +0ms - express:application booting in development mode +1ms - express:router use / query +0ms - express:router:layer new / +0ms - express:router use / expressInit +0ms - express:router:layer new / +0ms - express:router use / favicon +1ms - express:router:layer new / +0ms - express:router use / logger +0ms - express:router:layer new / +0ms - express:router use / jsonParser +0ms - express:router:layer new / +1ms - express:router use / urlencodedParser +0ms - express:router:layer new / +0ms - express:router use / cookieParser +0ms - express:router:layer new / +0ms - express:router use / stylus +90ms - express:router:layer new / +0ms - express:router use / serveStatic +0ms - express:router:layer new / +0ms - express:router use / router +0ms - express:router:layer new / +1ms - express:router use /users router +0ms - express:router:layer new /users +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms +$ DEBUG=express:*,router,router:* node index.js + express:application set "x-powered-by" to true +0ms + express:application set "etag" to 'weak' +3ms + express:application set "etag fn" to [Function: generateETag] +0ms + express:application set "env" to 'development' +1ms + express:application set "query parser" to 'simple' +0ms + express:application set "query parser fn" to [Function: parse] +0ms + express:application set "subdomain offset" to 2 +1ms + express:application set "trust proxy" to false +0ms + express:application set "trust proxy fn" to [Function: trustNone] +1ms + express:application booting in development mode +0ms + express:application set "view" to [Function: View] +0ms + express:application set "views" to '/projects/example/views' +1ms + express:application set "jsonp callback name" to 'callback' +0ms + router use '/' jsonParser +0ms + router:layer new '/' +0ms + router:route new '/' +0ms + router:layer new '/' +3ms + router:route get / +0ms + router:layer new '/' +1ms + router use '/users' router +4ms + router:layer new '/users' +0ms + router:route new '/' +1ms + router:layer new '/' +0ms + router:route get / +1ms + router:layer new '/' +1ms ``` アプリへのリクエストが行われると、Express コードで指定されたログが表示されます。 ```bash - express:router dispatching GET / +4h - express:router query : / +2ms - express:router expressInit : / +0ms - express:router favicon : / +0ms - express:router logger : / +1ms - express:router jsonParser : / +0ms - express:router urlencodedParser : / +1ms - express:router cookieParser : / +0ms - express:router stylus : / +0ms - express:router serveStatic : / +2ms - express:router router : / +2ms - express:router dispatching GET / +1ms - express:view lookup "index.pug" +338ms - express:view stat "/projects/example/views/index.pug" +0ms - express:view render "/projects/example/views/index.pug" +1ms + router dispatching GET /users +712ms + router jsonParser : /users +1ms + router trim prefix (/users) from url /users +2ms + router router /users : /users +0ms + router dispatching GET / +0ms +``` + +To see the logs only from the router implementation, set the value of `DEBUG` to `router,router:*`. 同様に、アプリケーションの実装からのログのみを見るには、`DEBUG`の値を`express:application`などに設定します。 + +## Using `debug` in your own code + +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: + + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); ``` -ルータの実装からのみログを見るには、`DEBUG`の値を`express:router`に設定します。 同様に、アプリケーションの実装からのログのみを見るには、`DEBUG`の値を`express:application`などに設定します。 同様に、アプリケーションの実装からのログのみを見るには、`DEBUG`の値を`express:application`などに設定します。 +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; -## `express` で生成されたアプリケーション +const debug = debugModule('myapp:server'); +const app = express(); -`express`コマンドによって生成されたアプリケーションは、`debug`モジュールを使用し、デバッグ名前空間はアプリケーションの名前をスコープします。 +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); -例えば、 `$ express sample-app` を使用してアプリを生成した場合、次のコマンドでデバッグ文を有効にできます。 +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` カンマ区切りの名前のリストを割り当てることで、複数のデバッグ名前空間を指定できます: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,router node index.js ``` +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*,router,router:*" } +} +``` + +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## 高度なオプション Node.js を介して実行する場合、デバッグログの動作を変更するいくつかの環境変数を設定できます。 diff --git a/src/content/docs/ja/5x/guide/error-handling.mdx b/src/content/docs/ja/5x/guide/error-handling.mdx index 2e8034e4d9..bcd9ce0964 100644 --- a/src/content/docs/ja/5x/guide/error-handling.mdx +++ b/src/content/docs/ja/5x/guide/error-handling.mdx @@ -15,6 +15,8 @@ import Alert from '@components/primitives/Alert/Alert.astro'; Express がルートハンドラと ミドルウェアの実行中に発生するすべてのエラーをキャッチすることが重要です。 +### Errors in synchronous code + ルートハンドラとミドルウェア 内の同期コードで発生するエラーは追加の作業を必要としません。 同期コードがエラーをスローする場合、Expressは キャッチして処理します。 例: 同期コードがエラーをスローする場合、Expressは @@ -34,52 +36,24 @@ app.get('/', (req: Request, res: Response) => { }); ``` -For errors returned from asynchronous functions invoked by route handlers -and middleware, you must pass them to the `next()` function, where Express will -catch and process them. 例: - -```js -app.get('/', (req, res, next) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` - -```ts -import { type Request, type Response, type NextFunction } from 'express'; - -app.get('/', (req: Request, res: Response, next: NextFunction) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` +### Errors in asynchronous code -Define error-handling middleware functions in the same way as other middleware functions, -except error-handling functions have four arguments instead of three: -`(err, req, res, next)`. -例: +The recommended way to write asynchronous handlers is with `async` functions. +Route handlers and middleware that return a Promise call `next(value)` +automatically when they reject or throw an error, and `async` functions always +return a Promise, so their errors reach Express with no extra work. 例: ```js -app.get('/user/:id', async (req, res, next) => { +app.get('/user/:id', async (req, res) => { const user = await getUserById(req.params.id); res.send(user); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', async (req: Request, res: Response) => { const user = await getUserById(req.params.id); res.send(user); }); @@ -93,49 +67,41 @@ the thrown error or the rejected value. 拒否された値が指定されてい Expressは現在のリクエストをエラーとみなし、 残っている非エラー処理ルーティングとミドルウェア関数をスキップします。 -シーケンス内のコールバックがデータを提供しない場合、エラーのみを提供する場合は、次のように -このコードを簡素化できます: +### Working with promise chains + +If you build a promise chain instead of using an `async` function, return the +promise from the handler and Express will likewise call `next` automatically +when it rejects: ```js -app.get('/', [ - function (req, res, next) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req, res) { - res.send('OK'); - }, -]); +app.get('/', (req, res) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/', [ - function (req: Request, res: Response, next: NextFunction) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req: Request, res: Response) { - res.send('OK'); - }, -]); +app.get('/', (req: Request, res: Response) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` -In the above example, `next` is provided as the callback for `fs.writeFile`, -which is called with or without errors. エラーがなければ、2番目の -ハンドラが実行されます。そうでなければ、Expressはエラーをキャッチして処理します。 - -route handler または -ミドルウェアによって呼び出された非同期コードで発生するエラーをキャッチし、処理のために Express に渡す必要があります。 例: 例: +If the promise is not returned, Express does not know it exists, and you must +route the error yourself by providing `next` as the final catch handler. +Without it, the rejection would be unhandled and crash the process: ```js app.get('/', (req, res, next) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` @@ -143,32 +109,32 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` -The above example uses a `try...catch` block to catch errors in the -asynchronous code and pass them to Express. 上の例では、 -非同期コードのエラーをキャッチし、Expressに渡すために`try...catch`ブロックを使用しています。 `try...catch` -ブロックが省略された場合、Expressは同期 -ハンドラコードの一部ではないため、エラーをキャッチしません。 +This works because if a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, `.catch` calls its handler with the error as the first argument, which is exactly the argument `next` expects, so the error reaches Express. + +### Working with callback APIs -プロミスを返す関数 -を使うと、`try...catch` のオーバーヘッドを避けることができます。 例: 例: +Errors produced by callback-based APIs, such as those in `node:fs`, are not +thrown and are not part of any promise. The callback receives them as its first +argument, and you must pass them to the `next()` function yourself, where +Express will catch and process them. 例: ```js app.get('/', (req, res, next) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` @@ -176,17 +142,46 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` -Since promises automatically catch both synchronous errors and rejected promises, -you can simply provide `next` as the final catch handler and Express will catch errors, -because the catch handler is given the error as the first argument. +シーケンス内のコールバックがデータを提供しない場合、エラーのみを提供する場合は、次のように +このコードを簡素化できます: + +```js +app.get('/', [ + function (req, res, next) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req, res) { + res.send('OK'); + }, +]); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', [ + function (req: Request, res: Response, next: NextFunction) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req: Request, res: Response) { + res.send('OK'); + }, +]); +``` + +In the above example, `next` is provided as the callback for `fs.writeFile`, +which is called with or without errors. エラーがなければ、2番目の +ハンドラが実行されます。そうでなければ、Expressはエラーをキャッチして処理します。 また、非同期コードを些細なものに減らすことで、同期エラー のキャッチに依存するハンドラのチェーンを使用することもできます。 例: 例: @@ -223,7 +218,7 @@ app.get('/', [ ]); ``` -The above example has a couple of trivial statements from the `readFile` +The above example contains a couple of trivial statements following the `readFile` call. 上の例では、`readFile` 呼び出しからいくつかの些細な文があります。 `readFile` でエラーが発生した場合、エラーは Express に渡されます。 それ以外の場合は、 チェーン内の次のハンドラ @@ -235,6 +230,42 @@ synchronous error handler will catch it. If you had done this processing inside the `readFile` callback, then the application might exit and the Express error handlers would not run. +Finally, for asynchronous code that provides no error-first callback, such as a +timer, catch errors inside the asynchronous code itself and pass them to +Express: + +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', (req: Request, res: Response, next: NextFunction) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +The above example uses a `try...catch` block to catch errors in the +asynchronous code and pass them to Express. 上の例では、 +非同期コードのエラーをキャッチし、Expressに渡すために`try...catch`ブロックを使用しています。 `try...catch` +ブロックが省略された場合、Expressは同期 +ハンドラコードの一部ではないため、エラーをキャッチしません。 + どちらの方法を使っても、Expressエラーハンドラを呼び出し、 アプリケーションを存続させたい場合は Express がエラーを受け取ることを確認する必要があります。 @@ -432,7 +463,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) この例でも、`clientErrorHandler`は以下のように定義されています。この場合、エラーは明示的に次のエラーに渡されます。 -Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/ja/5x/guide/overriding-express-api.mdx b/src/content/docs/ja/5x/guide/overriding-express-api.mdx index e80a7c127a..01323166be 100644 --- a/src/content/docs/ja/5x/guide/overriding-express-api.mdx +++ b/src/content/docs/ja/5x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -Express API は、リクエストオブジェクトとレスポンスオブジェクトのさまざまなメソッドとプロパティで構成されています。 これらはプロトタイプによって継承されます。 Express API には 2 つの拡張ポイントがあります。 These are inherited by prototype. There are two extension points for the Express API: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. These are inherited by prototype. There are two extension points for the Express API: 1. `express.request` と `express.response` のグローバルプロトタイプ。 2. `app.request`と`app.response`でアプリ固有のプロトタイプ。 diff --git a/src/content/docs/ja/5x/guide/routing.mdx b/src/content/docs/ja/5x/guide/routing.mdx index 384a0aeb5f..bf7a885a67 100644 --- a/src/content/docs/ja/5x/guide/routing.mdx +++ b/src/content/docs/ja/5x/guide/routing.mdx @@ -14,7 +14,7 @@ HTTPメソッドに対応するExpress `app` オブジェクトのメソッド see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. 言い換えれば、アプリケーションは指定されたルートとメソッドに一致するリクエストを「リッスン」します。 マッチを検出すると、指定されたコールバック関数を呼び出します。 +言い換えれば、アプリケーションは指定されたルートとメソッドに一致するリクエストを「リッスン」します。 マッチを検出すると、指定されたコールバック関数を呼び出します。 These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. 実際、ルーティングメソッドは引数として複数のコールバック関数を持つことができます。 複数のコールバック関数を使用。 コールバック関数に `next` を引数として渡し、関数の本体内で `next()` を呼び出して、次のコールバックに @@ -88,11 +88,13 @@ app.post('/', (req: Request, res: Response) => { }); ``` -Expressは、すべてのHTTPリクエストメソッドに対応するメソッドをサポートしています: `get`、`post`など。 -完全なリストについては、 [app.METHOD](/api/application#appmethodpath-callback--callback-) を参照してください。 -For a full list, see [app.METHOD](/api/application#appmethod). +HTTPメソッドに対応するExpress `app` オブジェクトのメソッドを使用してルーティングを定義します。 +のように、`app。 POST リクエストを処理する GET リクエストと `app.post\` を処理します。 For a full list, +see [app.METHOD](/api/application#appmethod). +You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to +specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -特別なルーティングメソッド`app.all()`があり、\_all_HTTPリクエストメソッドのパスにミドルウェア関数をロードするために使用されます。 例えば、`GET`を使用しているかどうかに関わらず、ルート`"/secret"へのリクエストに対して以下のハンドラが実行されます。 `POST`、`PUT`、`DELETE\`、または[http module](https://nodejs.org/api/http.html#http_http_methods)でサポートされている他のHTTPリクエストメソッド。 For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +特別なルーティングメソッド`app.all()`があり、\_all_HTTPリクエストメソッドのパスにミドルウェア関数をロードするために使用されます。 例えば、`GET`を使用しているかどうかに関わらず、ルート`"/secret"へのリクエストに対して以下のハンドラが実行されます。 `POST`、`PUT`、`DELETE\`、または[http module](https://nodejs.org/api/http.html#http_http_methods)でサポートされている他のHTTPリクエストメソッド。 For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -112,19 +114,20 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## ルートパス -ルートパスはリクエストメソッドと組み合わせて、リクエストを作成できるエンドポイントを定義します。 ルートパスは文字列または正規表現にすることができます。 Route paths can be strings or regular expressions. +ルートパスはリクエストメソッドと組み合わせて、リクエストを作成できるエンドポイントを定義します。 ルートパスは文字列または正規表現にすることができます。 Route paths can be strings or regular expressions. Route paths can be strings or regular expressions. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. Express はルートパスに一致する [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) v8 を使用します。ルートパスの定義におけるすべての可能性については、path-to-regexp ドキュメントを参照してください。 [Express Playground Router](https://bjohansebas.github.io/playground-router/)は、パターンマッチングをサポートしていませんが、基本的なExpressルートをテストするための便利なツールです。 [Express Playground Router](https://bjohansebas.github.io/playground-router/) is a handy tool for testing basic Express routes, although it does not support pattern matching. +[Express Playground Router](https://bjohansebas.github.io/playground-router/) is a handy tool for testing basic Express routes, although it does not support pattern matching. ### 文字列パス -文字列パスはリクエストと完全に一致します。 ドット(`.`)とハイフン(`-`)は文字通り解釈されます。 The dot (`.`) and hyphen (`-`) are interpreted literally. +文字列パスはリクエストと完全に一致します。 ドット(`.`)とハイフン(`-`)は文字通り解釈されます。 文字列パスはリクエストと完全に一致します。 ドット(`.`)とハイフン(`-`)は文字通り解釈されます。 The dot (`.`) and hyphen (`-`) are interpreted literally. クエリ文字列はルートパスの一部ではありません。 @@ -158,83 +161,15 @@ app.get('/random.text', (req: Request, res: Response) => { }); ``` -### ワイルドカード - -Wildcards match any path after a prefix. ワイルドカードはプレフィックスの後の任意のパスに一致します。 ルートパラメータと同様に名前が必要で、パスセグメントの配列として取得されます。 - -```js -app.get('/files/*filepath', (req, res) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -ルートパスに一致させるには、ワイルドカードを括弧で囲みます。 - -```js -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req, res) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req: Request, res: Response) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -### 任意のセグメント - -Use braces to define optional segments in a route path. ルートパスで任意のセグメントを定義するには、括弧を使用します。 セグメントが存在しない場合、パラメータは `req.params` から省略されます。 - -```js -app.get('/:file{.:ext}', (req, res) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/:file{.:ext}', (req: Request, res: Response) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -`?`、`+`、`*`、`[]`、`()`の文字は予約されており、ルートパスの文字列として使用することはできません。 必要に応じてエスケープするには`\`を使用します。 Use `\` to escape them if needed. +The characters `?`, `+`, `*`, `[]`, `()`, and `!` are reserved and cannot be used as literal characters in route paths, and braces are reserved for [optional segments](#optional-segments). Use `\` to escape them if needed. ### 正規表現 -正規表現をルートパスとして使用することもできます。 これは、より複雑なマッチングロジックが必要な場合に便利です。 This is useful when you need more complex matching logic. +正規表現をルートパスとして使用することもできます。 これは、より複雑なマッチングロジックが必要な場合に便利です。 正規表現をルートパスとして使用することもできます。 これは、より複雑なマッチングロジックが必要な場合に便利です。 This is useful when you need more complex matching logic. ```js // Matches any path containing "a" @@ -264,7 +199,11 @@ app.get(/.*fly$/, (req: Request, res: Response) => { ## ルートパラメータ -Route parameters are named URL segments that are used to capture the values specified at their position in the URL. ルートパラメータは、URL 内の位置で指定された値をキャプチャするために使用される名前付きの URL セグメントです。 取得した値は `req.params` オブジェクト内に入力され、パス内でそれぞれのキーとして指定されたrouteパラメータの名前が入力されます。 +Route parameters are named URL segments that are used to capture the values specified at their position in the URL. ルートパラメータは、URL 内の位置で指定された値をキャプチャするために使用される名前付きの URL セグメントです。 取得した値は `req.params` オブジェクト内に入力され、パス内でそれぞれのキーとして指定されたrouteパラメータの名前が入力されます。 They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces. + +### Named parameters + +Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below. ``` Route path: /users/:userId/books/:bookId @@ -298,7 +237,7 @@ app.get('/users/:userId/books/:bookId', sendParams); -ルートパラメータの名前は、"単語文字" ([A-Za-z0-9_] )で構成されている必要があります。 +The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example `:"user-name"`. @@ -318,15 +257,122 @@ req.params: { "genus": "Prunus", "species": "persica" } -正規表現文字はルートパスではサポートされていません。 代わりにパスまたは正規表現の配列を使用してください。 -詳細については、[パスルートマッチング構文](/guide/migrating-5#path-syntax)を参照してください。 Use an array of paths or regular expressions instead. +Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as `:userId(\d+)`. Use an array of paths or a full regular expression instead. See the [path route matching syntax](/guide/migrating-5#path-route-matching-syntax) for more information. +### ワイルドカード + +Wildcards match any path after a prefix. Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string. + +```js +app.get('/files/*filepath', (req, res) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +ルートパスに一致させるには、ワイルドカードを括弧で囲みます。 + +```js +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req, res) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req: Request, res: Response) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +### 任意のセグメント + +Use braces to define optional segments in a route path. ルートパスで任意のセグメントを定義するには、括弧を使用します。 セグメントが存在しない場合、パラメータは `req.params` から省略されます。 + +```js +app.get('/:file{.:ext}', (req, res) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/:file{.:ext}', (req: Request, res: Response) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters: + +```js +app.get('/user/\{:id}', (req, res) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req, res) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/user/\{:id}', (req: Request, res: Response) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req: Request, res: Response) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +ルートパス内のスラッシュの位置を、リクエスト URL に関する[`strict routing` 設定](/api/application/#application-settings)と混同しないでください。この設定は、ルートパスが要求していないスラッシュで終わる URL が一致するかどうかを制御します。 たとえば、`/order/` へのリクエストはデフォルトでは `/order{/:id}` ルートに一致しますが、strict routing が有効な場合は 404 エラーを返します。`/user/` の末尾のスラッシュは、`/user/\{:id}` ルートがそれを必須としているため影響を受けません。 上記の例でコメントされているすべてのリクエストは、この設定に関係なく同じように動作します。## Route handlersYou can provide multiple callback functions that + ## Route handlers -リクエストを処理するために、 [middleware](/guide/using-middleware) のように動作する複数のコールバック関数を提供できます。 唯一の例外は、これらのコールバックが `next('route')` を呼び出して、残りのルートコールバックをバイパスすることです。 このメカニズムを使用して、ルート上に事前条件を設定できます。 次に現在のルートを進める理由がなければ次のルートに制御を渡す。 The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route. +リクエストを処理するために、 [middleware](/guide/using-middleware) のように動作する複数のコールバック関数を提供できます。 唯一の例外は、これらのコールバックが `next('route')` を呼び出して、残りのルートコールバックをバイパスすることです。 このメカニズムを使用して、ルート上に事前条件を設定できます。 次に現在のルートを進める理由がなければ次のルートに制御を渡す。 The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route.```js +app.get('/user/:id', (req, res, next) => { +if (req.params.i + +```` ```js app.get('/user/:id', (req, res, next) => { @@ -339,7 +385,7 @@ app.get('/user/:id', (req, res, next) => { app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0'); }); -``` +```` ```ts import { type Request, type Response, type NextFunction } from 'express'; @@ -361,15 +407,17 @@ app.get('/user/:id', (req: Request, res: Response) => { - `GET /user/5` → 最初のルートで処理 → "User 5" を送信 - `GET /user/0` → 最初のroute ('route')`を呼び出し、次に一致する `/user/:id\` route (ルート) をスキップします。 -ルートハンドラは、次の例に示すように、関数、関数の配列、または両方の組み合わせの形式で使用できます。 +ルートハンドラは、次の例に示すように、関数、関数の配列、または両方の組み合わせの形式で使用できます。A single callback function can handle a route. For example:```js + +```` -単一のコールバック関数はルートを処理できます。 例: 例: +単一のコールバック関数はルートを処理できます。 例: ```js app.get('/example/a', (req, res) => { res.send('Hello from A!'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -379,7 +427,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -複数のコールバック関数がルートを処理できます (`next` オブジェクトを指定してください)。 例: 例: +複数のコールバック関数がルートを処理できます (`next` オブジェクトを指定してください)。 例: 例: 例: ```js app.get( @@ -409,7 +457,7 @@ app.get( ); ``` -コールバック関数の配列はルートを処理できます。 例: 例: +コールバック関数の配列はルートを処理できます。 例: ```js const cb0 = function (req, res, next) { @@ -449,7 +497,7 @@ const cb2 = function (req: Request, res: Response) { app.get('/example/c', [cb0, cb1, cb2]); ``` -独立した関数と関数の配列の組み合わせは、ルートを処理することができます。 例: 例: +独立した関数と関数の配列の組み合わせは、ルートを処理することができます。 例: 例: 例: ```js const cb0 = function (req, res, next) { @@ -503,27 +551,34 @@ app.get( ## レスポンスメソッド -次の表のレスポンスオブジェクト (`res`) のメソッドは、クライアントにレスポンスを送信し、リクエスト応答のサイクルを終了することができます。 これらのメソッドのいずれもルートハンドラから呼び出されない場合、クライアントリクエストはハングしたままになります。 If none of these methods are called from a route handler, the client request will be left hanging. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging.| Method | Description -| 方法 | 説明 | -| ----------------------------------------------- | ---------------------------------------------------------------------------------- | -| [res.download()](/api/response#resdownload) | ダウンロードするファイルを指示します。 | -| [res.end()](/api/response#resend) | 応答プロセスを終了します。 | -| [res.json()](/api/response#resjson) | JSON 応答を送信します。 | -| [res.jsonp()](/api/response#resjsonp) | JSONP サポートを使用して JSON 応答を送信します。 | -| [res.redirect()](/api/response#resredirect) | Redirect a request. | -| [res.render()](/api/response#resrender) | ビューテンプレートをレンダリングします。 | -| [res.send()](/api/response#ressend) | さまざまなタイプの応答を送信します。 | -| [res.sendFile()](/api/response#ressendfile) | ファイルをオクテットストリームとして送信する。 | -| [res.sendStatus()](/api/response#ressendstatus) | レスポンスステータスコードを設定し、文字列表現をレスポンスボディとして送信します。 | +| | | +| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/api/response#resdownload) | ダウンロードするファイルを指示します。 | +| [res.end()](/api/response#resend) | 応答プロセスを終了します。 | +| [res.json()](/api/response#resjson) | JSON 応答を送信します。 | +| [res.jsonp()](/api/response#resjsonp) | JSONP サポートを使用して JSON 応答を送信します。 | +| | Redirect a request. | +| [res.render()](/api/response#resrender) | ビューテンプレートをレンダリングします。 | +| [res.send()](/api/response#ressend) | さまざまなタイプの応答を送信します。 | +| [res.sendFile()](/api/response#ressendfile) | ファイルをオクテットストリームとして送信する。 | +| [res.sendStatus()](/api/response#ressendstatus) | レスポンスステータスコードを設定し、文字列表現をレスポンスボディとして送信します。 \|## app.route()You can create chainable route handlers for a rou \|## app.route()You can create chainable route handlers for a rou | ## app.route() `app.route()` を使用すると、ルートパスに対してチェーン可能なルートハンドラを作成できます。 パスは単一の場所で指定されているため、モジュラールートを作成することは、冗長性とタイプミスを削減するのに役立ちます。 ルートの詳細については、以下を参照してください: [Router() documentation](/api/router)。 -Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router).Here is an example of chained route handlers that are defined by us + +以下は、`app.route()`を使用して定義されたルートハンドラの例です。```js +app +.route('/book') +.get((req, res) => { +res.send('Ge -以下は、`app.route()`を使用して定義されたルートハンドラの例です。 +```` ```js app @@ -537,7 +592,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -557,9 +612,9 @@ app ## express.Router -Use the `express.Router` class to create modular, mountable route handlers. `express.Router` クラスを使用して、モジュール化されたマウント可能なルートハンドラを作成します。 `Router`インスタンスは完全なミドルウェアとルーティングシステムです。そのため、しばしば「ミニアプリ」と呼ばれます。 +Use the `express.Router` class to create modular, mountable route handlers. `express.Router` クラスを使用して、モジュール化されたマウント可能なルートハンドラを作成します。 `Router`インスタンスは完全なミドルウェアとルーティングシステムです。そのため、しばしば「ミニアプリ」と呼ばれます。The following example creates a router as a module, loads a middlewThe following example creates a router as a module, loads a middlew -次の例では、ルータをモジュールとして作成し、ミドルウェア関数をロードします。 いくつかのルートを定義し、メインアプリのパスにルータモジュールをマウントします。 +次の例では、ルータをモジュールとして作成し、ミドルウェア関数をロードします。 いくつかのルートを定義し、メインアプリのパスにルータモジュールをマウントします。Create a router file named `birds.js` in the app directory, with thCreate a router file named `birds.js` in the app directory, with th appディレクトリに`birds.js`という名前のルーターファイルを作成します。以下の内容を使用します。 @@ -652,10 +707,13 @@ import birds from './birds'; app.use('/birds', birds); ``` -アプリは `/birds` と `/birds/about` へのリクエストを処理できるようになりました。 同様に、ルート固有の「timeLog」ミドルウェア関数を呼び出します。 +アプリは `/birds` と `/birds/about` へのリクエストを処理できるようになりました。 同様に、ルート固有の「timeLog」ミドルウェア関数を呼び出します。But if the parent route `/birds` has path parameters, it will not b -ただし、親ルート `/birds` にパスパラメータがある場合、サブルートからデフォルトではアクセスできません。 アクセス可能にするには、 `mergeParams` オプションを Router コンストラクタ [reference](/api/application#appusepath-callback--callback) に渡す必要があります。 To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +ただし、親ルート `/birds` にパスパラメータがある場合、サブルートからデフォルトではアクセスできません。 アクセス可能にするには、 `mergeParams` オプションを Router コンストラクタ [reference](/api/application#appusepath-callback--callback) に渡す必要があります。 ただし、親ルート `/birds` にパスパラメータがある場合、サブルートからデフォルトではアクセスできません。 アクセス可能にするには、 `mergeParams` オプションを Router コンストラクタ [reference](/api/application#appusepath-callback--callback) に渡す必要があります。 To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter).```js +const router = express.Router({ mergeParams: true }); + +```` ```js const router = express.Router({ mergeParams: true }); -``` +```` diff --git a/src/content/docs/ja/5x/guide/using-middleware.mdx b/src/content/docs/ja/5x/guide/using-middleware.mdx index 3b358e9c2b..1afb89651f 100644 --- a/src/content/docs/ja/5x/guide/using-middleware.mdx +++ b/src/content/docs/ja/5x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Express.jsアプリケーションでミドルウェアを使用す import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express はルーティングおよびミドルウェアの Web フレームワークで、独自の最小限の機能を持っています。Express アプリケーションは、基本的にはミドルウェア関数の一連の呼び出しです。 +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -_Middleware_ 関数は、[request object](/api#req) (`req`) にアクセスできる関数です。 [response object](/api#res) (`res`) と、アプリケーションのリクエストレスポンスサイクルの次のミドルウェア関数。 次のミドルウェア関数は通常`next`という名前の変数で表されます。 次のミドルウェア関数は通常`next`という名前の変数で表されます。 +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` ミドルウェア機能は以下のタスクを実行できます。 - 任意のコードを実行します。 -- リクエストとレスポンスオブジェクトに変更を加えます。 +- Modify the request and response objects. - リクエストレスポンスサイクルを終了します。 -- スタック内の次のミドルウェア関数を呼び出します。 +- Pass control to the next middleware function. -現在のミドルウェア関数がリクエスト応答サイクルを終了しない場合は、次のミドルウェア関数に制御を渡すために `next()` を呼び出す必要があります。 そうでなければ、リクエストはハングアップのままになります。 そうでなければ、リクエストはハングアップのままになります。 +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. そうでなければ、リクエストはハングアップのままになります。 Express アプリケーションでは、次のタイプのミドルウェアを使用できます。 @@ -28,14 +33,15 @@ Express アプリケーションでは、次のタイプのミドルウェアを - [Third-party middleware](#middleware.third-party) アプリケーションレベルおよびルーターレベルのミドルウェアは、任意のマウントパスでロードできます。 -また、一連のミドルウェア関数を一緒にロードして、マウントポイントでミドルウェアシステムのサブスタックを作成することもできます。 -また、一連のミドルウェア関数を一緒にロードして、マウントポイントでミドルウェアシステムのサブスタックを作成することもできます。 +また、一連のミドルウェア関数を一緒にロードして、マウントポイントでミドルウェアシステムのサブスタックを作成することもできます。 Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## アプリケーションレベルのミドルウェア -`app.use()` と `app()` を使用して、アプリケーションレベルのミドルウェアを [app object](/api#app) のインスタンスにバインドします。 ETHOD()関数。`METHOD`はミドルウェア関数が小文字で処理するHTTPメソッドです(GET、PUT、POSTなど)。 +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -この例では、マウントパスのないミドルウェア関数を示します。 この関数はアプリがリクエストを受け取るたびに実行されます。 この関数はアプリがリクエストを受け取るたびに実行されます。 +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -69,8 +75,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -This example shows a middleware function mounted on the `/user/:id` path. この例では、`/user/:id` パスにマウントされたミドルウェア関数を示します。 関数は `/user/:id` パス上の任意のタイプの -HTTP リクエストに対して実行されます。 +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -88,24 +95,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Route handlers + This example shows a route and its handler function (middleware system). この例ではルートとハンドラ関数(ミドルウェアシステム)を示します。 関数は`/user/:id`パスへのGETリクエストを処理します。 ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Here is an example of loading a series of middleware functions at a mount point, with a mount path. -It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the `/user/:id` path. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -137,9 +147,9 @@ app.use( ); ``` -Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. +### Multiple route handlers -この例では、`/user/:id`パスへのGETリクエストを処理するミドルウェアサブスタックを示します。 +Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. ```js app.get( @@ -148,13 +158,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -168,18 +178,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -他のミドルウェア関数をルータのミドルウェアスタックからスキップするには、次のルートに制御を渡すために `next('route')` を呼び出します。 +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -188,7 +200,7 @@ app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { -この例では、`/user/:id`パスへのGETリクエストを処理するミドルウェアサブスタックを示します。 +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -199,14 +211,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -222,21 +234,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -ミドルウェアは、再利用可能な配列で宣言することもできます。 +### Reusable middleware arrays -この例では、`/user/:id`パスへのGETリクエストを処理するミドルウェアサブスタックを持つ配列を示しています。 +Middleware functions can also be grouped into arrays for better reusability. この例では、`/user/:id`パスへのGETリクエストを処理するミドルウェアサブスタックを持つ配列を示しています。 ```js function logOriginalUrl(req, res, next) { @@ -250,7 +262,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -269,14 +281,14 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## ルーターレベルのミドルウェア -ルータレベルのミドルウェアは、`express.Router()`のインスタンスにバインドされている場合を除き、アプリケーションレベルのミドルウェアと同じ方法で動作します。 +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); @@ -320,19 +332,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -370,19 +382,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -420,19 +432,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -441,10 +453,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -ルーターのミドルウェア関数の残りをスキップするには、`next('router')` -を呼び出してルーターインスタンスからコントロールを渡します。 +### Skipping out of a router + +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. -この例では、`/user/:id`パスへのGETリクエストを処理するミドルウェアサブスタックを示します。 +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -513,15 +526,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## エラー処理のミドルウェア - - -Error-handling middleware always takes _four_ arguments. You must provide four arguments to -identify it as an error-handling middleware function. Even if you don't need to use the `next` -object, you must specify it to maintain the signature. Otherwise, the `next` object will be -interpreted as regular middleware and will fail to handle errors. - - - 他のミドルウェア関数と同じ方法でエラー処理ミドルウェア関数を定義します 3 つの代わりに 4 つの引数を指定する場合を除き、特に \`(err, req, res, next) というシグネチャを使用します。 ```js @@ -540,18 +544,30 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -エラー処理ミドルウェアの詳細については、[Error handling](/guide/error-handling)を参照してください。 + -## 組み込みのミドルウェア +Error-handling middleware always takes _four_ arguments. You must provide four arguments to +identify it as an error-handling middleware function. Even if you don't need to use the `next` +object, you must specify it to maintain the signature. Otherwise, the `next` object will be +interpreted as regular middleware and will fail to handle errors. + + + + -Starting with version 4.x, Express no longer depends on [Connect](https://github.com/senchalabs/connect). バージョン 4.x 以降、Express は [Connect](https://github.com/senchalabs/connect) に依存しなくなりました。 The middleware -functions that were previously included with Express are now in separate modules; see [the list of middleware functions](https://github.com/senchalabs/connect#middleware). +For more information, see the [Error handling](/guide/error-handling) guide. + + + +## 組み込みのミドルウェア Express には次のミドルウェア関数が組み込まれています。 - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. -- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** -- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** +- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. +- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. ## Third-party middleware @@ -592,4 +608,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Expressで一般的に使用されるサードパーティミドルウェア関数の部分的なリストについては、[サードパーティミドルウェア](/resources/middleware)を参照してください。 + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/ja/5x/guide/using-template-engines.mdx b/src/content/docs/ja/5x/guide/using-template-engines.mdx index afa905188e..488eceec20 100644 --- a/src/content/docs/ja/5x/guide/using-template-engines.mdx +++ b/src/content/docs/ja/5x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Express でテンプレートエンジンを使用する -description: Pug、Handlebars、EJSなどのテンプレートエンジンをExpress.jsで統合して使用し、動的なHTMLページを効率的にレンダリングする方法をご覧ください。 +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -11,15 +11,15 @@ _template engine_ を使用すると、アプリケーションで静的なテ このアプローチにより、HTML ページのデザインが容易になります。 このアプローチにより、HTML ページのデザインが容易になります。 -The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it also supports [Handlebars](https://www.npmjs.com/package/handlebars), and [EJS](https://www.npmjs.com/package/ejs), among others. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views` テンプレートファイルがあるディレクトリ。 例: `app.set('views', './views')` 。 デフォルトはアプリケーションのルートディレクトリにある `views` ディレクトリです。 - `viewengine` を使用するテンプレートエンジン。 `viewengine` を使用するテンプレートエンジン。 たとえば、Pugテンプレートエンジンを使用するには、`app.set('view engine', 'pug')`を使います。 -次に、対応するテンプレートエンジン npm パッケージをインストールします。例えば、Pug をインストールする場合: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -29,6 +29,7 @@ Pug のような Express 準拠のテンプレートエンジンは、 `__expres 一部のテンプレートエンジンはこの規約に従っていません。 一部のテンプレートエンジンはこの規約に従っていません。 [@ladjs/integrate](https://www.npmjs.com/package/@ladjs/consolidate) ライブラリは、一般的な Node.js テンプレートエンジンのすべてをマッピングすることによって、この規則に従っており、したがって、Express 内でシームレスに動作します。 +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/ja/5x/guide/writing-middleware.mdx b/src/content/docs/ja/5x/guide/writing-middleware.mdx index 4c7b7581a3..7501149694 100644 --- a/src/content/docs/ja/5x/guide/writing-middleware.mdx +++ b/src/content/docs/ja/5x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Express.jsアプリケーション用にカスタムミドルウェ --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Middleware_ 関数は、[request object](/api#req) (`req`) にアクセスできる関数です。 [response object](/api#res) (`res`)とアプリケーションのリクエストレスポンスサイクルの中の `next` 関数。 `next` 関数はExpressルータ内の関数で、呼び出されたときに現在のミドルウェアを継承してミドルウェアを実行します。 `next` 関数はExpressルータ内の関数で、呼び出されたときに現在のミドルウェアを継承してミドルウェアを実行します。 @@ -173,8 +174,8 @@ app.listen(3000); ### ミドルウェア関数requestTime -次に、"requestTime" というミドルウェア関数を作成し、リクエストオブジェクトに `requestTime` -というプロパティを追加します。 +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -398,9 +399,13 @@ functions. -リクエストオブジェクト、レスポンスオブジェクト、スタック内の次のミドルウェア関数、そしてノード全体にアクセスできるためです。 s API、ミドルウェア関数の可能性は無限大です。 +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Express ミドルウェアの詳細については、[Express ミドルウェアを使用する](/guide/using-middleware)を参照してください。 + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## 設定可能なミドルウェア diff --git a/src/content/docs/ja/5x/starter/basic-routing.mdx b/src/content/docs/ja/5x/starter/basic-routing.mdx index be14ee4b41..7ad621db6f 100644 --- a/src/content/docs/ja/5x/starter/basic-routing.mdx +++ b/src/content/docs/ja/5x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Express.jsアプリケーションでルーティングの基礎を --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ は、アプリケーションが特定のエンドポイントに対してどのように応答するかを決定することを指します。 これはURI(またはパス)と特定のHTTPリクエストメソッド(GET、POSTなど)です。 @@ -97,4 +98,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -For more details about routing, see the [routing guide](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/ja/5x/starter/faq.mdx b/src/content/docs/ja/5x/starter/faq.mdx index c2969010f4..51c20a6cdf 100644 --- a/src/content/docs/ja/5x/starter/faq.mdx +++ b/src/content/docs/ja/5x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Express.jsについてよく寄せられる質問の答えを見つけましょう。その中には、アプリケーション構造、モデル、認証、テンプレートエンジン、エラー処理などのトピックが含まれます。 --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## アプリケーションを構成するにはどうすればいいですか? There is no definitive answer to this question. この質問には決定的な答えはありません。 The answer depends @@ -49,7 +51,11 @@ To normalize template engine interfaces and caching, see the [consolidate.js](https://github.com/visionmedia/consolidate.js) project for support. Unlisted template engines might still support the Express signature. -詳しくは、[Expressでテンプレートエンジンを使用する](/guide/using-template-engines)を参照してください。 + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## 404応答はどのように処理すればいいですか? @@ -100,7 +106,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -詳細については、[Error handling](/guide/error-handling)を参照してください。 + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## プレーンHTMLをレンダリングするにはどうすればいいですか? diff --git a/src/content/docs/ja/5x/starter/installing.mdx b/src/content/docs/ja/5x/starter/installing.mdx index bd1abc9172..ae41f06ecd 100644 --- a/src/content/docs/ja/5x/starter/installing.mdx +++ b/src/content/docs/ja/5x/starter/installing.mdx @@ -70,7 +70,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/ja/5x/starter/static-files.mdx b/src/content/docs/ja/5x/starter/static-files.mdx index 9ce3278bac..057af002f1 100644 --- a/src/content/docs/ja/5x/starter/static-files.mdx +++ b/src/content/docs/ja/5x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: 組み込みの 'static' ミドルウェアを使用して、Expres --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; 画像、CSSファイル、JavaScriptファイルなどの静的ファイルを提供するには、Express で組み込まれているミドルウェア関数「express.static」を使用します。 @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + `serve-static` 関数とそのオプションの詳細については、 [serve-static](/resources/middleware/serve-static) を参照してください。 + + diff --git a/src/content/docs/ko/4x/guide/debugging.mdx b/src/content/docs/ko/4x/guide/debugging.mdx index 24bbce3510..db5740d8a2 100644 --- a/src/content/docs/ko/4x/guide/debugging.mdx +++ b/src/content/docs/ko/4x/guide/debugging.mdx @@ -4,6 +4,7 @@ description: Learn how to enable and use debugging logs in Express.js applicatio --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*` when launching your app. @@ -86,22 +87,119 @@ When a request is then made to the app, you will see the logs specified in the E To see the logs only from the router implementation, set the value of `DEBUG` to `express:router`. Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on. -## Applications generated by `express` +## Using `debug` in your own code -An application generated by the `express` command uses the `debug` module and its debug namespace is scoped to the name of the application. +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: -For example, if you generated the app with `$ express sample-app`, you can enable the debug statements with the following command: + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; + +const debug = debugModule('myapp:server'); +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` You can specify more than one debug namespace by assigning a comma-separated list of names: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,express:router node index.js +``` + +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*" } +} ``` +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Advanced options When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: diff --git a/src/content/docs/ko/4x/guide/error-handling.mdx b/src/content/docs/ko/4x/guide/error-handling.mdx index 7cafabc5f6..de6641684c 100644 --- a/src/content/docs/ko/4x/guide/error-handling.mdx +++ b/src/content/docs/ko/4x/guide/error-handling.mdx @@ -62,14 +62,16 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Starting with Express 5, route handlers and middleware that return a Promise -will call `next(value)` automatically when they reject or throw an error. -For example: +Errors from rejected promises are not passed to `next` automatically, and this includes `async` functions: if an `async` route handler throws or awaits a rejected promise, the rejection is unhandled, which crashes the process on current Node.js versions. You must catch the error yourself and pass it to Express: ```js app.get('/user/:id', async (req, res, next) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` @@ -77,14 +79,22 @@ app.get('/user/:id', async (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` -If `getUserById` throws an error or rejects, `next` will be called with either -the thrown error or the rejected value. If no rejected value is provided, `next` -will be called with a default Error object provided by the Express router. + + +Consider [updating to Express 5](/guide/migrating-5), where route handlers and middleware that +return a Promise call `next(value)` automatically when they reject or throw an error, making the +`try...catch` above unnecessary. + + If you pass anything to the `next()` function (except the string `'route'`), Express regards the current request as being an error and will skip any @@ -180,9 +190,7 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Since promises automatically catch both synchronous errors and rejected promises, -you can simply provide `next` as the final catch handler and Express will catch errors, -because the catch handler is given the error as the first argument. +If a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, passing `next` as the handler is enough: `.catch` calls it with the error as its first argument, which is exactly the argument `next` expects, so the error reaches Express. You could also use a chain of handlers to rely on synchronous error catching, by reducing the asynchronous code to something trivial. For example: @@ -219,7 +227,7 @@ app.get('/', [ ]); ``` -The above example has a couple of trivial statements from the `readFile` +The above example contains a couple of trivial statements following the `readFile` call. If `readFile` causes an error, then it passes the error to Express, otherwise you quickly return to the world of synchronous error handling in the next handler in the chain. Then, the example above tries to process the data. If this fails, then the @@ -424,7 +432,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Also in this example, `clientErrorHandler` is defined as follows; in this case, the error is explicitly passed along to the next one. -Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/ko/4x/guide/overriding-express-api.mdx b/src/content/docs/ko/4x/guide/overriding-express-api.mdx index 54cef9edbc..c6afcac28b 100644 --- a/src/content/docs/ko/4x/guide/overriding-express-api.mdx +++ b/src/content/docs/ko/4x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -The Express API consists of various methods and properties on the request and response objects. These are inherited by prototype. There are two extension points for the Express API: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. These are inherited by prototype. There are two extension points for the Express API: 1. The global prototypes at `express.request` and `express.response`. 2. App-specific prototypes at `app.request` and `app.response`. diff --git a/src/content/docs/ko/4x/guide/routing.mdx b/src/content/docs/ko/4x/guide/routing.mdx index 71afe6a955..c626f1f74a 100644 --- a/src/content/docs/ko/4x/guide/routing.mdx +++ b/src/content/docs/ko/4x/guide/routing.mdx @@ -13,7 +13,7 @@ for example, `app.get()` to handle GET requests and `app.post` to handle POST re see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function. +In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function. These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. In fact, the routing methods can have more than one callback function as arguments. With multiple callback functions, it is important to provide `next` as an argument to the callback function and then call `next()` within the body of the function to hand off control @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. For a full list, see [app.METHOD](/api/application#appmethod). -There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Route paths -Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions. +Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -235,6 +235,26 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => { }); ``` +A wildcard (`*`) on its own matches anything at its position, including entire subpaths. For example, this route path will match `/file/style.css` as well as `/file/javascripts/jquery.js`. Wildcards are unnamed, so the matched value is available as `req.params[0]` instead of a named parameter. + +```js +app.get('/file/*', (req, res) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/file/*', (req: Request, res: Response) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + ### Route paths based on regular expressions @@ -348,6 +368,14 @@ characters with an additional backslash, for example `\d+`. The [`*`](https://github.com/expressjs/express/issues/2495) character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. +Unlike named route parameters, wildcard (`*`) matches in [string patterns](#route-paths-based-on-string-patterns) and capture groups in regular expressions are unnamed: their values are available by position, as `req.params[0]`, `req.params[1]`, and so on. + +``` +Route path: /file/*/size/* +Request URL: http://localhost:3000/file/javascripts/jquery.js/size/large +req.params: { "0": "javascripts/jquery.js", "1": "large" } +``` + ## Route handlers You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route. @@ -387,7 +415,7 @@ In this example: Route handlers can be in the form of a function, an array of functions, or combinations of both, as shown in the following examples. -A single callback function can handle a route. For example: +More than one callback function can handle a route (make sure you specify the `next` object). For example: ```js app.get('/example/a', (req, res) => { @@ -403,7 +431,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -More than one callback function can handle a route (make sure you specify the `next` object). For example: +A combination of independent functions and arrays of functions can handle a route. For example: ```js app.get( @@ -527,7 +555,7 @@ app.get( ## Response methods -The methods on the response object (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging.| Method | Description | Method | Description | | ----------------------------------------------- | ------------------------------------------------------------------------------------- | @@ -544,9 +572,9 @@ The methods on the response object (`res`) in the following table can send a res ## app.route() You can create chainable route handlers for a route path by using `app.route()`. -Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router). -Here is an example of chained route handlers that are defined by using `app.route()`. +|## app.route()You can create chainable route handlers for a rou ```js app @@ -580,9 +608,9 @@ app ## express.Router -Use the `express.Router` class to create modular, mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app". +Use the `express.Router` class to create modular, mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app".The following example creates a router as a module, loads a middlew -The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app. +The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app.Create a router file named `birds.js` in the app directory, with th Create a router file named `birds.js` in the app directory, with the following content: @@ -677,7 +705,7 @@ app.use('/birds', birds); The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route. -But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter). ```js const router = express.Router({ mergeParams: true }); diff --git a/src/content/docs/ko/4x/guide/using-middleware.mdx b/src/content/docs/ko/4x/guide/using-middleware.mdx index a0862b0b4f..2d2d18d3ca 100644 --- a/src/content/docs/ko/4x/guide/using-middleware.mdx +++ b/src/content/docs/ko/4x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Learn how to use middleware in Express.js applications, including a import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express is a routing and middleware web framework that has minimal functionality of its own: An Express application is essentially a series of middleware function calls. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -_Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the next middleware function in the application's request-response cycle. The next middleware function is commonly denoted by a variable named `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Middleware functions can perform the following tasks: - Execute any code. -- Make changes to the request and the response objects. +- Modify the request and response objects. - End the request-response cycle. -- Call the next middleware function in the stack. +- Pass control to the next middleware function. -If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging. An Express application can use the following types of middleware: @@ -27,14 +32,15 @@ An Express application can use the following types of middleware: - [Built-in middleware](#middleware.built-in) - [Third-party middleware](#middleware.third-party) -You can load application-level and router-level middleware with an optional mount path. -You can also load a series of middleware functions together, which creates a sub-stack of the middleware system at a mount point. +You can load application-level and router-level middleware with an optional mount path. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Application-level middleware -Bind application-level middleware to an instance of the [app object](/api#app) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -This example shows a middleware function with no mount path. The function is executed every time the app receives a request. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -This example shows a middleware function mounted on the `/user/:id` path. The function is executed for any type of -HTTP request on the `/user/:id` path. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` -This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path. +### Route handlers + +This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path: ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Here is an example of loading a series of middleware functions at a mount point, with a mount path. -It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the `/user/:id` path. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. +### Multiple route handlers -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -To skip the rest of the middleware functions from a router middleware stack, call `next('route')` to pass control to the next route. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ To skip the rest of the middleware functions from a router middleware stack, cal -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Middleware can also be declared in an array for reusability. +### Reusable middleware arrays -This example shows an array with a middleware sub-stack that handles GET requests to the `/user/:id` path +Middleware functions can also be grouped into arrays for better reusability. This example shows an array with a middleware sub-stack that handles GET requests to the `/user/:id` path: ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,19 +280,25 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Router-level middleware -Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); ``` +```ts +import express from 'express'; + +const router = express.Router(); +``` + Load router-level middleware by using the `router.use()` and `router.METHOD()` functions. The following example code replicates the middleware system that is shown above for application-level middleware, by using router-level middleware: @@ -313,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -363,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -413,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -434,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -To skip the rest of the router's middleware functions, call `next('router')` -to pass control back out of the router instance. +### Skipping out of a router -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. + +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -506,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Error-handling middleware - - -Error-handling middleware always takes _four_ arguments. You must provide four arguments to -identify it as an error-handling middleware function. Even if you don't need to use the `next` -object, you must specify it to maintain the signature. Otherwise, the `next` object will be -interpreted as regular middleware and will fail to handle errors. - - - Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature `(err, req, res, next)`: ```js @@ -533,7 +543,20 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For details about error-handling middleware, see: [Error handling](/guide/error-handling). + + +Error-handling middleware always takes _four_ arguments. You must provide four arguments to +identify it as an error-handling middleware function. Even if you don't need to use the `next` +object, you must specify it to maintain the signature. Otherwise, the `next` object will be +interpreted as regular middleware and will fail to handle errors. + + + + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Built-in middleware @@ -544,6 +567,8 @@ Express has the following built-in middleware functions: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. - [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. **NOTE: Available with Express 4.17.0+** +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. **NOTE: Available with Express 4.17.0+** - [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** ## Third-party middleware @@ -552,7 +577,7 @@ Use third-party middleware to add functionality to Express apps. Install the Node.js module for the required functionality, then load it in your app at the application level or at the router level. -The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`. +The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`: @@ -585,4 +610,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -For a partial list of third-party middleware functions that are commonly used with Express, see: [Third-party middleware](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/ko/4x/guide/using-template-engines.mdx b/src/content/docs/ko/4x/guide/using-template-engines.mdx index 18284a627d..d097a96420 100644 --- a/src/content/docs/ko/4x/guide/using-template-engines.mdx +++ b/src/content/docs/ko/4x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Using template engines with Express -description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ A _template engine_ enables you to use static template files in your application variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page. -The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it also supports [Handlebars](https://www.npmjs.com/package/handlebars), and [EJS](https://www.npmjs.com/package/ejs), among others. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, the directory where the template files are located. Eg: `app.set('views', './views')`. This defaults to the `views` directory in the application root directory. - `view engine`, the template engine to use. For example, to use the Pug template engine: `app.set('view engine', 'pug')`. -Then install the corresponding template engine npm package; for example to install Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ which `res.render()` calls to render the template code. Some template engines do not follow this convention. The [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) library follows this convention by mapping all of the popular Node.js template engines, and therefore works seamlessly within Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/ko/4x/guide/writing-middleware.mdx b/src/content/docs/ko/4x/guide/writing-middleware.mdx index 37b925af2c..650570479e 100644 --- a/src/content/docs/ko/4x/guide/writing-middleware.mdx +++ b/src/content/docs/ko/4x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Learn how to write custom middleware functions for Express.js appli --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the `next` function in the application's request-response cycle. The `next` function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware. @@ -200,7 +201,7 @@ The middleware function `myLogger` simply prints a message, then passes on the r ### Middleware function requestTime Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` -to the request object. +to the [request object](/api/request). @@ -420,9 +421,13 @@ functions. -Because you have access to the request object, the response object, the next middleware function in the stack, and the whole Node.js API, the possibilities with middleware functions are endless. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -For more information about Express middleware, see: [Using Express middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Configurable middleware diff --git a/src/content/docs/ko/4x/starter/basic-routing.mdx b/src/content/docs/ko/4x/starter/basic-routing.mdx index ef4d06764d..b75994c83a 100644 --- a/src/content/docs/ko/4x/starter/basic-routing.mdx +++ b/src/content/docs/ko/4x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Learn the fundamentals of routing in Express.js applications, inclu --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -For more details about routing, see the [routing guide](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/ko/4x/starter/faq.mdx b/src/content/docs/ko/4x/starter/faq.mdx index 89c07591cf..1931f06ae1 100644 --- a/src/content/docs/ko/4x/starter/faq.mdx +++ b/src/content/docs/ko/4x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## How should I structure my application? There is no definitive answer to this question. The answer depends @@ -42,7 +44,11 @@ To normalize template engine interfaces and caching, see the [consolidate.js](https://github.com/visionmedia/consolidate.js) project for support. Unlisted template engines might still support the Express signature. -For more information, see [Using template engines with Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## How do I handle 404 responses? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For more information, see [Error handling](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## How do I render plain HTML? diff --git a/src/content/docs/ko/4x/starter/installing.mdx b/src/content/docs/ko/4x/starter/installing.mdx index 2b040edf10..1b0a095d6a 100644 --- a/src/content/docs/ko/4x/starter/installing.mdx +++ b/src/content/docs/ko/4x/starter/installing.mdx @@ -79,7 +79,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/ko/4x/starter/static-files.mdx b/src/content/docs/ko/4x/starter/static-files.mdx index 15a901a994..73872efd6c 100644 --- a/src/content/docs/ko/4x/starter/static-files.mdx +++ b/src/content/docs/ko/4x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Understand how to serve static files like images, CSS, and JavaScri --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; To serve static files such as images, CSS files, and JavaScript files, use the `express.static` built-in middleware function in Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + For more details about the `serve-static` function and its options, see [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/ko/5x/guide/debugging.mdx b/src/content/docs/ko/5x/guide/debugging.mdx index 24bbce3510..62b6303e5e 100644 --- a/src/content/docs/ko/5x/guide/debugging.mdx +++ b/src/content/docs/ko/5x/guide/debugging.mdx @@ -4,104 +4,218 @@ description: Learn how to enable and use debugging logs in Express.js applicatio --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -To see all the internal logs used in Express, set the `DEBUG` environment variable to -`express:*` when launching your app. +To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*,router,router:*` when launching your app. Routing is handled by the separate [router](https://github.com/pillarjs/router) package, so its logs live under the `router` namespace and are not included in `express:*`. ```bash -$ DEBUG=express:* node index.js +$ DEBUG=express:*,router,router:* node index.js ``` On Windows, use the corresponding command. ```bash -> $env:DEBUG = "express:*"; node index.js +> $env:DEBUG = "express:*,router,router:*"; node index.js ``` -Running this command on the default app generated by the [express generator](/starter/generator) prints the following output: +Running this command on a small app with a JSON body parser and a mounted router prints the following output: + +```cjs title="index.cjs" +const express = require('express'); + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` + +```mjs title="index.mjs" +import express from 'express'; + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` ```bash -$ DEBUG=express:* node ./bin/www - express:router:route new / +0ms - express:router:layer new / +1ms - express:router:route get / +1ms - express:router:layer new / +0ms - express:router:route new / +1ms - express:router:layer new / +0ms - express:router:route get / +0ms - express:router:layer new / +0ms - express:application compile etag weak +1ms - express:application compile query parser extended +0ms - express:application compile trust proxy false +0ms - express:application booting in development mode +1ms - express:router use / query +0ms - express:router:layer new / +0ms - express:router use / expressInit +0ms - express:router:layer new / +0ms - express:router use / favicon +1ms - express:router:layer new / +0ms - express:router use / logger +0ms - express:router:layer new / +0ms - express:router use / jsonParser +0ms - express:router:layer new / +1ms - express:router use / urlencodedParser +0ms - express:router:layer new / +0ms - express:router use / cookieParser +0ms - express:router:layer new / +0ms - express:router use / stylus +90ms - express:router:layer new / +0ms - express:router use / serveStatic +0ms - express:router:layer new / +0ms - express:router use / router +0ms - express:router:layer new / +1ms - express:router use /users router +0ms - express:router:layer new /users +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms +$ DEBUG=express:*,router,router:* node index.js + express:application set "x-powered-by" to true +0ms + express:application set "etag" to 'weak' +3ms + express:application set "etag fn" to [Function: generateETag] +0ms + express:application set "env" to 'development' +1ms + express:application set "query parser" to 'simple' +0ms + express:application set "query parser fn" to [Function: parse] +0ms + express:application set "subdomain offset" to 2 +1ms + express:application set "trust proxy" to false +0ms + express:application set "trust proxy fn" to [Function: trustNone] +1ms + express:application booting in development mode +0ms + express:application set "view" to [Function: View] +0ms + express:application set "views" to '/projects/example/views' +1ms + express:application set "jsonp callback name" to 'callback' +0ms + router use '/' jsonParser +0ms + router:layer new '/' +0ms + router:route new '/' +0ms + router:layer new '/' +3ms + router:route get / +0ms + router:layer new '/' +1ms + router use '/users' router +4ms + router:layer new '/users' +0ms + router:route new '/' +1ms + router:layer new '/' +0ms + router:route get / +1ms + router:layer new '/' +1ms ``` When a request is then made to the app, you will see the logs specified in the Express code: ```bash - express:router dispatching GET / +4h - express:router query : / +2ms - express:router expressInit : / +0ms - express:router favicon : / +0ms - express:router logger : / +1ms - express:router jsonParser : / +0ms - express:router urlencodedParser : / +1ms - express:router cookieParser : / +0ms - express:router stylus : / +0ms - express:router serveStatic : / +2ms - express:router router : / +2ms - express:router dispatching GET / +1ms - express:view lookup "index.pug" +338ms - express:view stat "/projects/example/views/index.pug" +0ms - express:view render "/projects/example/views/index.pug" +1ms + router dispatching GET /users +712ms + router jsonParser : /users +1ms + router trim prefix (/users) from url /users +2ms + router router /users : /users +0ms + router dispatching GET / +0ms +``` + +To see the logs only from the router implementation, set the value of `DEBUG` to `router,router:*`. Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on. + +## Using `debug` in your own code + +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: + + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); ``` -To see the logs only from the router implementation, set the value of `DEBUG` to `express:router`. Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on. +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; -## Applications generated by `express` +const debug = debugModule('myapp:server'); +const app = express(); -An application generated by the `express` command uses the `debug` module and its debug namespace is scoped to the name of the application. +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); -For example, if you generated the app with `$ express sample-app`, you can enable the debug statements with the following command: +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` You can specify more than one debug namespace by assigning a comma-separated list of names: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,router node index.js ``` +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*,router,router:*" } +} +``` + +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Advanced options When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: diff --git a/src/content/docs/ko/5x/guide/error-handling.mdx b/src/content/docs/ko/5x/guide/error-handling.mdx index f933d9e32b..a5b202c501 100644 --- a/src/content/docs/ko/5x/guide/error-handling.mdx +++ b/src/content/docs/ko/5x/guide/error-handling.mdx @@ -14,6 +14,8 @@ handler so you don't need to write your own to get started. It's important to ensure that Express catches all errors that occur while running route handlers and middleware. +### Errors in synchronous code + Errors that occur in synchronous code inside route handlers and middleware require no extra work. If synchronous code throws an error, then Express will catch and process it. For example: @@ -32,51 +34,24 @@ app.get('/', (req: Request, res: Response) => { }); ``` -For errors returned from asynchronous functions invoked by route handlers -and middleware, you must pass them to the `next()` function, where Express will -catch and process them. For example: - -```js -app.get('/', (req, res, next) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` +### Errors in asynchronous code -```ts -import { type Request, type Response, type NextFunction } from 'express'; - -app.get('/', (req: Request, res: Response, next: NextFunction) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` - -Starting with Express 5, route handlers and middleware that return a Promise -will call `next(value)` automatically when they reject or throw an error. -For example: +The recommended way to write asynchronous handlers is with `async` functions. +Route handlers and middleware that return a Promise call `next(value)` +automatically when they reject or throw an error, and `async` functions always +return a Promise, so their errors reach Express with no extra work. For example: ```js -app.get('/user/:id', async (req, res, next) => { +app.get('/user/:id', async (req, res) => { const user = await getUserById(req.params.id); res.send(user); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', async (req: Request, res: Response) => { const user = await getUserById(req.params.id); res.send(user); }); @@ -90,49 +65,41 @@ If you pass anything to the `next()` function (except the string `'route'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. -If the callback in a sequence provides no data, only errors, you can simplify -this code as follows: +### Working with promise chains + +If you build a promise chain instead of using an `async` function, return the +promise from the handler and Express will likewise call `next` automatically +when it rejects: ```js -app.get('/', [ - function (req, res, next) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req, res) { - res.send('OK'); - }, -]); +app.get('/', (req, res) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/', [ - function (req: Request, res: Response, next: NextFunction) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req: Request, res: Response) { - res.send('OK'); - }, -]); +app.get('/', (req: Request, res: Response) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` -In the above example, `next` is provided as the callback for `fs.writeFile`, -which is called with or without errors. If there is no error, the second -handler is executed, otherwise Express catches and processes the error. - -You must catch errors that occur in asynchronous code invoked by route handlers or -middleware and pass them to Express for processing. For example: +If the promise is not returned, Express does not know it exists, and you must +route the error yourself by providing `next` as the final catch handler. +Without it, the rejection would be unhandled and crash the process: ```js app.get('/', (req, res, next) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` @@ -140,31 +107,32 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` -The above example uses a `try...catch` block to catch errors in the -asynchronous code and pass them to Express. If the `try...catch` -block were omitted, Express would not catch the error since it is not part of the synchronous -handler code. +This works because if a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, `.catch` calls its handler with the error as the first argument, which is exactly the argument `next` expects, so the error reaches Express. -Use promises to avoid the overhead of the `try...catch` block or when using functions -that return promises. For example: +### Working with callback APIs + +Errors produced by callback-based APIs, such as those in `node:fs`, are not +thrown and are not part of any promise. The callback receives them as its first +argument, and you must pass them to the `next()` function yourself, where +Express will catch and process them. For example: ```js app.get('/', (req, res, next) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` @@ -172,17 +140,46 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` -Since promises automatically catch both synchronous errors and rejected promises, -you can simply provide `next` as the final catch handler and Express will catch errors, -because the catch handler is given the error as the first argument. +If the callback in a sequence provides no data, only errors, you can simplify +this code as follows: + +```js +app.get('/', [ + function (req, res, next) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req, res) { + res.send('OK'); + }, +]); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', [ + function (req: Request, res: Response, next: NextFunction) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req: Request, res: Response) { + res.send('OK'); + }, +]); +``` + +In the above example, `next` is provided as the callback for `fs.writeFile`, +which is called with or without errors. If there is no error, the second +handler is executed, otherwise Express catches and processes the error. You could also use a chain of handlers to rely on synchronous error catching, by reducing the asynchronous code to something trivial. For example: @@ -219,7 +216,7 @@ app.get('/', [ ]); ``` -The above example has a couple of trivial statements from the `readFile` +The above example contains a couple of trivial statements following the `readFile` call. If `readFile` causes an error, then it passes the error to Express, otherwise you quickly return to the world of synchronous error handling in the next handler in the chain. Then, the example above tries to process the data. If this fails, then the @@ -227,6 +224,41 @@ synchronous error handler will catch it. If you had done this processing inside the `readFile` callback, then the application might exit and the Express error handlers would not run. +Finally, for asynchronous code that provides no error-first callback, such as a +timer, catch errors inside the asynchronous code itself and pass them to +Express: + +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', (req: Request, res: Response, next: NextFunction) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +The above example uses a `try...catch` block to catch errors in the +asynchronous code and pass them to Express. If the `try...catch` +block were omitted, Express would not catch the error since it is not part of the synchronous +handler code. + Whichever method you use, if you want Express error handlers to be called in and the application to survive, you must ensure that Express receives the error. @@ -424,7 +456,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Also in this example, `clientErrorHandler` is defined as follows; in this case, the error is explicitly passed along to the next one. -Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/ko/5x/guide/overriding-express-api.mdx b/src/content/docs/ko/5x/guide/overriding-express-api.mdx index 54cef9edbc..c6afcac28b 100644 --- a/src/content/docs/ko/5x/guide/overriding-express-api.mdx +++ b/src/content/docs/ko/5x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -The Express API consists of various methods and properties on the request and response objects. These are inherited by prototype. There are two extension points for the Express API: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. These are inherited by prototype. There are two extension points for the Express API: 1. The global prototypes at `express.request` and `express.response`. 2. App-specific prototypes at `app.request` and `app.response`. diff --git a/src/content/docs/ko/5x/guide/routing.mdx b/src/content/docs/ko/5x/guide/routing.mdx index aafdbb401e..0e4393b208 100644 --- a/src/content/docs/ko/5x/guide/routing.mdx +++ b/src/content/docs/ko/5x/guide/routing.mdx @@ -13,7 +13,7 @@ for example, `app.get()` to handle GET requests and `app.post` to handle POST re see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function. +In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function. These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. In fact, the routing methods can have more than one callback function as arguments. With multiple callback functions, it is important to provide `next` as an argument to the callback function and then call `next()` within the body of the function to hand off control @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. For a full list, see [app.METHOD](/api/application#appmethod). -There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Route paths -Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings or regular expressions. +Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings or regular expressions. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -153,77 +153,9 @@ app.get('/random.text', (req: Request, res: Response) => { }); ``` -### Wildcards - -Wildcards match any path after a prefix. They must have a name, just like route parameters, and are captured as arrays of path segments. - -```js -app.get('/files/*filepath', (req, res) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -To also match the root path, wrap the wildcard in braces: - -```js -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req, res) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req: Request, res: Response) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -### Optional segments - -Use braces to define optional segments in a route path. When the segment is not present, the parameter is omitted from `req.params`. - -```js -app.get('/:file{.:ext}', (req, res) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/:file{.:ext}', (req: Request, res: Response) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -The characters `?`, `+`, `*`, `[]`, and `()` are reserved and cannot be used as literal characters in route paths. Use `\` to escape them if needed. +The characters `?`, `+`, `*`, `[]`, `()`, and `!` are reserved and cannot be used as literal characters in route paths, and braces are reserved for [optional segments](#optional-segments). Use `\` to escape them if needed. @@ -259,7 +191,11 @@ app.get(/.*fly$/, (req: Request, res: Response) => { ## Route parameters -Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter specified in the path as their respective keys. +Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter specified in the path as their respective keys. They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces. + +### Named parameters + +Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below. ``` Route path: /users/:userId/books/:bookId @@ -293,7 +229,7 @@ app.get('/users/:userId/books/:bookId', sendParams); -The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]). +The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example `:"user-name"`. @@ -313,14 +249,122 @@ req.params: { "genus": "Prunus", "species": "persica" } -Regexp characters are not supported in route paths. Use an array of paths or regular expressions instead. +Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as `:userId(\d+)`. Use an array of paths or a full regular expression instead. See the [path route matching syntax](/guide/migrating-5#path-syntax) for more information. +### Wildcards + +Wildcards match any path after a prefix. Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string. + +```js +app.get('/files/*filepath', (req, res) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +To also match the root path, wrap the wildcard in braces: + +```js +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req, res) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req: Request, res: Response) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +### Optional segments + +Use braces to define optional segments in a route path. When the segment is not present, the parameter is omitted from `req.params`. + +```js +app.get('/:file{.:ext}', (req, res) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/:file{.:ext}', (req: Request, res: Response) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters: + +```js +app.get('/user/\{:id}', (req, res) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req, res) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/user/\{:id}', (req: Request, res: Response) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req: Request, res: Response) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +라우트 경로에서 슬래시의 위치를 요청 URL에 관한 [`strict routing` 설정](/api/application/#application-settings)과 혼동하지 마세요. 이 설정은 라우트 경로가 요구하지 않는 슬래시로 끝나는 URL이 여전히 일치하는지를 제어합니다. 예를 들어 `/order/` 요청은 기본적으로 `/order{/:id}` 라우트와 일치하지만, strict routing이 활성화되면 404 오류를 반환합니다. `/user/`의 끝 슬래시는 `/user/\{:id}` 라우트가 이를 요구하므로 영향을 받지 않습니다. 위 예제에서 주석으로 표시된 모든 요청은 이 설정과 관계없이 동일하게 동작합니다.## Route handlersYou can provide multiple callback functions that + ## Route handlers -You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route. +You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route.```js +app.get('/user/:id', (req, res, next) => { +if (req.params.i + +```` ```js app.get('/user/:id', (req, res, next) => { @@ -333,7 +377,7 @@ app.get('/user/:id', (req, res, next) => { app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0'); }); -``` +```` ```ts import { type Request, type Response, type NextFunction } from 'express'; @@ -355,15 +399,17 @@ In this example: - `GET /user/5` → handled by first route → sends "User 5" - `GET /user/0` → first route calls `next('route')`, skipping to the next matching `/user/:id` route -Route handlers can be in the form of a function, an array of functions, or combinations of both, as shown in the following examples. +Route handlers can be in the form of a function, an array of functions, or combinations of both, as shown in the following examples.A single callback function can handle a route. For example:```js + +```` -A single callback function can handle a route. For example: +More than one callback function can handle a route (make sure you specify the `next` object). ```js app.get('/example/a', (req, res) => { res.send('Hello from A!'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -373,7 +419,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -More than one callback function can handle a route (make sure you specify the `next` object). For example: +A combination of independent functions and arrays of functions can handle a route. For example: ```js app.get( @@ -403,7 +449,7 @@ app.get( ); ``` -An array of callback functions can handle a route. For example: +An array of callback functions can handle a route. ```js const cb0 = function (req, res, next) { @@ -497,26 +543,32 @@ app.get( ## Response methods -The methods on the response object (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging.| Method | Description| Method | Description -| Method | Description | -| ----------------------------------------------- | ------------------------------------------------------------------------------------- | -| [res.download()](/api/response#resdownload) | Prompt a file to be downloaded. | -| [res.end()](/api/response#resend) | End the response process. | -| [res.json()](/api/response#resjson) | Send a JSON response. | -| [res.jsonp()](/api/response#resjsonp) | Send a JSON response with JSONP support. | -| [res.redirect()](/api/response#resredirect) | Redirect a request. | -| [res.render()](/api/response#resrender) | Render a view template. | -| [res.send()](/api/response#ressend) | Send a response of various types. | -| [res.sendFile()](/api/response#ressendfile) | Send a file as an octet stream. | -| [res.sendStatus()](/api/response#ressendstatus) | Set the response status code and send its string representation as the response body. | +| | | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/api/response#resdownload) | Prompt a file to be downloaded. | +| [res.end()](/api/response#resend) | End the response process. | +| [res.json()](/api/response#resjson) | Send a JSON response. | +| [res.jsonp()](/api/response#resjsonp) | Send a JSON response with JSONP support. | +| | Redirect a request. | +| [res.render()](/api/response#resrender) | Render a view template. | +| [res.send()](/api/response#ressend) | Send a response of various types. | +| [res.sendFile()](/api/response#ressendfile) | Send a file as an octet stream. | +| [res.sendStatus()](/api/response#ressendstatus) | Set the response status code and send its string representation as the response body. \|## app.route()You can create chainable route handlers for a rou | ## app.route() You can create chainable route handlers for a route path by using `app.route()`. -Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router).Here is an example of chained route handlers that are defined by us + +|## app.route()You can create chainable route handlers for a rou```js +app +.route('/book') +.get((req, res) => { +res.send('Ge -Here is an example of chained route handlers that are defined by using `app.route()`. +```` ```js app @@ -530,7 +582,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -550,9 +602,9 @@ app ## express.Router -Use the `express.Router` class to create modular, mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app". +Use the `express.Router` class to create modular, mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app".The following example creates a router as a module, loads a middlewThe following example creates a router as a module, loads a middlew -The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app. +The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app.Create a router file named `birds.js` in the app directory, with thCreate a router file named `birds.js` in the app directory, with th Create a router file named `birds.js` in the app directory, with the following content: @@ -645,10 +697,13 @@ import birds from './birds'; app.use('/birds', birds); ``` -The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route. +The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route.But if the parent route `/birds` has path parameters, it will not b -But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter).```js +const router = express.Router({ mergeParams: true }); + +```` ```js const router = express.Router({ mergeParams: true }); -``` +```` diff --git a/src/content/docs/ko/5x/guide/using-middleware.mdx b/src/content/docs/ko/5x/guide/using-middleware.mdx index 282234bb84..53c84df475 100644 --- a/src/content/docs/ko/5x/guide/using-middleware.mdx +++ b/src/content/docs/ko/5x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Learn how to use middleware in Express.js applications, including a import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express is a routing and middleware web framework that has minimal functionality of its own: An Express application is essentially a series of middleware function calls. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -_Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the next middleware function in the application's request-response cycle. The next middleware function is commonly denoted by a variable named `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Middleware functions can perform the following tasks: - Execute any code. -- Make changes to the request and the response objects. +- Modify the request and response objects. - End the request-response cycle. -- Call the next middleware function in the stack. +- Pass control to the next middleware function. -If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging. An Express application can use the following types of middleware: @@ -27,14 +32,15 @@ An Express application can use the following types of middleware: - [Built-in middleware](#middleware.built-in) - [Third-party middleware](#middleware.third-party) -You can load application-level and router-level middleware with an optional mount path. -You can also load a series of middleware functions together, which creates a sub-stack of the middleware system at a mount point. +You can load application-level and router-level middleware with an optional mount path. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Application-level middleware -Bind application-level middleware to an instance of the [app object](/api#app) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -This example shows a middleware function with no mount path. The function is executed every time the app receives a request. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -This example shows a middleware function mounted on the `/user/:id` path. The function is executed for any type of -HTTP request on the `/user/:id` path. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` -This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path. +### Route handlers + +This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path: ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Here is an example of loading a series of middleware functions at a mount point, with a mount path. -It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the `/user/:id` path. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. +### Multiple route handlers -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -To skip the rest of the middleware functions from a router middleware stack, call `next('route')` to pass control to the next route. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ To skip the rest of the middleware functions from a router middleware stack, cal -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Middleware can also be declared in an array for reusability. +### Reusable middleware arrays -This example shows an array with a middleware sub-stack that handles GET requests to the `/user/:id` path +Middleware functions can also be grouped into arrays for better reusability. This example shows an array with a middleware sub-stack that handles GET requests to the `/user/:id` path: ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,14 +280,14 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Router-level middleware -Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); @@ -319,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -369,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -419,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -440,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -To skip the rest of the router's middleware functions, call `next('router')` -to pass control back out of the router instance. +### Skipping out of a router + +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -512,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Error-handling middleware - - -Error-handling middleware always takes _four_ arguments. You must provide four arguments to -identify it as an error-handling middleware function. Even if you don't need to use the `next` -object, you must specify it to maintain the signature. Otherwise, the `next` object will be -interpreted as regular middleware and will fail to handle errors. - - - Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature `(err, req, res, next)`: ```js @@ -539,18 +543,30 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For details about error-handling middleware, see: [Error handling](/guide/error-handling). + -## Built-in middleware +Error-handling middleware always takes _four_ arguments. You must provide four arguments to +identify it as an error-handling middleware function. Even if you don't need to use the `next` +object, you must specify it to maintain the signature. Otherwise, the `next` object will be +interpreted as regular middleware and will fail to handle errors. + + + + -Starting with version 4.x, Express no longer depends on [Connect](https://github.com/senchalabs/connect). The middleware -functions that were previously included with Express are now in separate modules; see [the list of middleware functions](https://github.com/senchalabs/connect#middleware). +For more information, see the [Error handling](/guide/error-handling) guide. + + + +## Built-in middleware Express has the following built-in middleware functions: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. -- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** -- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** +- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. +- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. ## Third-party middleware @@ -558,7 +574,7 @@ Use third-party middleware to add functionality to Express apps. Install the Node.js module for the required functionality, then load it in your app at the application level or at the router level. -The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`. +The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`: @@ -591,4 +607,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -For a partial list of third-party middleware functions that are commonly used with Express, see: [Third-party middleware](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/ko/5x/guide/using-template-engines.mdx b/src/content/docs/ko/5x/guide/using-template-engines.mdx index 18284a627d..d097a96420 100644 --- a/src/content/docs/ko/5x/guide/using-template-engines.mdx +++ b/src/content/docs/ko/5x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Using template engines with Express -description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ A _template engine_ enables you to use static template files in your application variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page. -The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it also supports [Handlebars](https://www.npmjs.com/package/handlebars), and [EJS](https://www.npmjs.com/package/ejs), among others. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, the directory where the template files are located. Eg: `app.set('views', './views')`. This defaults to the `views` directory in the application root directory. - `view engine`, the template engine to use. For example, to use the Pug template engine: `app.set('view engine', 'pug')`. -Then install the corresponding template engine npm package; for example to install Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ which `res.render()` calls to render the template code. Some template engines do not follow this convention. The [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) library follows this convention by mapping all of the popular Node.js template engines, and therefore works seamlessly within Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/ko/5x/guide/writing-middleware.mdx b/src/content/docs/ko/5x/guide/writing-middleware.mdx index b3a0c5d9c4..f164a2d7ca 100644 --- a/src/content/docs/ko/5x/guide/writing-middleware.mdx +++ b/src/content/docs/ko/5x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Learn how to write custom middleware functions for Express.js appli --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the `next` function in the application's request-response cycle. The `next` function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware. @@ -171,7 +172,7 @@ The middleware function `myLogger` simply prints a message, then passes on the r ### Middleware function requestTime Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` -to the request object. +to the [request object](/api/request). @@ -391,9 +392,13 @@ functions. -Because you have access to the request object, the response object, the next middleware function in the stack, and the whole Node.js API, the possibilities with middleware functions are endless. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -For more information about Express middleware, see: [Using Express middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Configurable middleware diff --git a/src/content/docs/ko/5x/starter/basic-routing.mdx b/src/content/docs/ko/5x/starter/basic-routing.mdx index ef4d06764d..b75994c83a 100644 --- a/src/content/docs/ko/5x/starter/basic-routing.mdx +++ b/src/content/docs/ko/5x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Learn the fundamentals of routing in Express.js applications, inclu --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -For more details about routing, see the [routing guide](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/ko/5x/starter/faq.mdx b/src/content/docs/ko/5x/starter/faq.mdx index b75a4aeabc..194db26b08 100644 --- a/src/content/docs/ko/5x/starter/faq.mdx +++ b/src/content/docs/ko/5x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## How should I structure my application? There is no definitive answer to this question. The answer depends @@ -42,7 +44,11 @@ To normalize template engine interfaces and caching, see the [consolidate.js](https://github.com/visionmedia/consolidate.js) project for support. Unlisted template engines might still support the Express signature. -For more information, see [Using template engines with Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## How do I handle 404 responses? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For more information, see [Error handling](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## How do I render plain HTML? diff --git a/src/content/docs/ko/5x/starter/installing.mdx b/src/content/docs/ko/5x/starter/installing.mdx index 27a32d62dd..e320885aca 100644 --- a/src/content/docs/ko/5x/starter/installing.mdx +++ b/src/content/docs/ko/5x/starter/installing.mdx @@ -70,7 +70,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/ko/5x/starter/static-files.mdx b/src/content/docs/ko/5x/starter/static-files.mdx index 15a901a994..73872efd6c 100644 --- a/src/content/docs/ko/5x/starter/static-files.mdx +++ b/src/content/docs/ko/5x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Understand how to serve static files like images, CSS, and JavaScri --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; To serve static files such as images, CSS files, and JavaScript files, use the `express.static` built-in middleware function in Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + For more details about the `serve-static` function and its options, see [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/pt-br/4x/guide/debugging.mdx b/src/content/docs/pt-br/4x/guide/debugging.mdx index 7570928696..1929e12368 100644 --- a/src/content/docs/pt-br/4x/guide/debugging.mdx +++ b/src/content/docs/pt-br/4x/guide/debugging.mdx @@ -4,6 +4,7 @@ description: Aprenda a habilitar e usar logs de depuração nos aplicativos Expr --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; Para ver todos os logs internos usados no Express, defina a variável de ambiente `DEBUG` para `express:*` ao iniciar seu aplicativo. @@ -86,22 +87,119 @@ Quando um pedido for feito ao aplicativo, você verá os logs especificados no c Para ver os logs apenas da implementação do roteador, defina o valor de `DEBUG` para `express:router`. Da mesma forma, para ver apenas os logs da implementação do aplicativo, defina o valor de `DEBUG` para `express:application`, e assim por diante. -## Aplicações geradas por `express` +## Using `debug` in your own code -Uma aplicação gerada pelo comando `express` usa o módulo `debug` e seu namespace de depuração é escopo para o nome da aplicação. +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: -Por exemplo, se você gerou o app com `$ express sample-app`, você pode ativar as instruções de depuração com o seguinte comando: + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; + +const debug = debugModule('myapp:server'); +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` Você pode especificar mais de um namespace de depuração atribuindo uma lista de nomes separada por vírgulas: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,express:router node index.js +``` + +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*" } +} ``` +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Opções avançadas Ao executar através do Node.js, você pode definir algumas variáveis de ambiente que irão mudar o comportamento do log de depuração: diff --git a/src/content/docs/pt-br/4x/guide/error-handling.mdx b/src/content/docs/pt-br/4x/guide/error-handling.mdx index e635732678..fb9e9926ee 100644 --- a/src/content/docs/pt-br/4x/guide/error-handling.mdx +++ b/src/content/docs/pt-br/4x/guide/error-handling.mdx @@ -62,14 +62,16 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Começando pelo Express 5, roteadores e intermediários que retornam um Promise -chamarão `next(value)` automaticamente quando eles rejeitarem ou lançarem um erro. -Por exemplo: +Errors from rejected promises are not passed to `next` automatically, and this includes `async` functions: if an `async` route handler throws or awaits a rejected promise, the rejection is unhandled, which crashes the process on current Node.js versions. You must catch the error yourself and pass it to Express: ```js app.get('/user/:id', async (req, res, next) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` @@ -77,14 +79,22 @@ app.get('/user/:id', async (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` -Se `getUserById` lança um erro ou rejeita, `next` será chamado com -o erro lançado ou o valor rejeitado. Se nenhum valor rejeitado for fornecido, `next` -será chamado com um objeto de erro padrão fornecido pelo roteador Express. + + +Consider [updating to Express 5](/guide/migrating-5), where route handlers and middleware that +return a Promise call `next(value)` automatically when they reject or throw an error, making the +`try...catch` above unnecessary. + + Se você passar qualquer coisa para a função `next()` (exceto a string `'route'`), Expressa que a requisição atual é um erro e irá pular quaisquer funções @@ -180,9 +190,7 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Since promises automatically catch both synchronous errors and rejected promises, -you can simply provide `next` as the final catch handler and Express will catch errors, -because the catch handler is given the error as the first argument. +If a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, passing `next` as the handler is enough: `.catch` calls it with the error as its first argument, which is exactly the argument `next` expects, so the error reaches Express. Se você tiver um gerenciador de rotas com múltiplas funções de retorno de chamada, você pode usar o parâmetro `rota` para pular para o próximo manipulador de rota. Por exemplo: @@ -218,8 +226,8 @@ app.get('/', [ ]); ``` -O exemplo acima tem algumas declarações triviais da chamada `readFile` -. If `readFile` causes an error, then it passes the error to Express, otherwise you +The above example contains a couple of trivial statements following the `readFile` +call. If `readFile` causes an error, then it passes the error to Express, otherwise you quickly return to the world of synchronous error handling in the next handler in the chain. Então, o exemplo acima tenta processar os dados. Se isso falhar, o manipulador de erro síncrono irá pegá-lo. Se você tivesse feito este processamento dentro do @@ -423,7 +431,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Também neste exemplo, `clientErrorHandler` é definido como segue; neste caso, o erro é explicitamente passado para o próximo. -Observe que quando _não_ estiver chamando "próximo" em uma função de manipulação de erros, você é responsável por escrever (e terminar) a resposta. Caso contrário, esses pedidos ficarão "pendentes" e não serão elegíveis para a recolha de lixo. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Caso contrário, esses pedidos ficarão "pendentes" e não serão elegíveis para a recolha de lixo. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/pt-br/4x/guide/overriding-express-api.mdx b/src/content/docs/pt-br/4x/guide/overriding-express-api.mdx index be37b5c875..a9a483bf97 100644 --- a/src/content/docs/pt-br/4x/guide/overriding-express-api.mdx +++ b/src/content/docs/pt-br/4x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -A API do Expresso consiste de vários métodos e propriedades nos objetos de solicitação e resposta. Estas são herdadas pelo protótipo. Há dois pontos de extensão para a API Express: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. Estas são herdadas pelo protótipo. Há dois pontos de extensão para a API Express: 1. Os protótipos globais em `express.request` e `express.response`. 2. Protótipos específicos de aplicativo em `app.request` e `app.response`. diff --git a/src/content/docs/pt-br/4x/guide/routing.mdx b/src/content/docs/pt-br/4x/guide/routing.mdx index 3ef174aa9e..ccb8793876 100644 --- a/src/content/docs/pt-br/4x/guide/routing.mdx +++ b/src/content/docs/pt-br/4x/guide/routing.mdx @@ -13,7 +13,7 @@ por exemplo, `app. et()` para lidar com solicitações GET e `app.post` para lid see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. Em outras palavras, o aplicativo "listas" para solicitações que correspondem com a(s) rota(s) e método(s) especificado(s), e quando ela detecta uma correspondência, ela chama a função de retorno de chamada especificado. +Em outras palavras, o aplicativo "listas" para solicitações que correspondem com a(s) rota(s) e método(s) especificado(s), e quando ela detecta uma correspondência, ela chama a função de retorno de chamada especificado. Em outras palavras, o aplicativo "listas" para solicitações que correspondem com a(s) rota(s) e método(s) especificado(s), e quando ela detecta uma correspondência, ela chama a função de retorno de chamada especificado. Na verdade, os métodos de roteamento podem ter mais de uma função de callback como argumentos. Com múltiplas funções de callback, é importante fornecer `next` como um argumento para a função de callback e então chamar `next()` dentro do corpo da função para liberar o controle @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Expresso suporta métodos que correspondem a todos os métodos de requisição HTTP: `get`, `post`, e assim por diante. For a full list, see [app.METHOD](/api/application#appmethod). -Há um método de roteamento especial, `app.all()`, usado para carregar funções de middleware em um caminho para os métodos de requisição HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +Há um método de roteamento especial, `app.all()`, usado para carregar funções de middleware em um caminho para os métodos de requisição HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Caminho da rota -Roteamento, em combinação com um método de solicitação, defina os pontos de extremidade em que as solicitações podem ser feitas. Caminhos de rota podem ser frases, padrões de strings ou expressões regulares. +Roteamento, em combinação com um método de solicitação, defina os pontos de extremidade em que as solicitações podem ser feitas. Caminhos de rota podem ser frases, padrões de strings ou expressões regulares. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -235,6 +235,26 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => { }); ``` +A wildcard (`*`) on its own matches anything at its position, including entire subpaths. For example, this route path will match `/file/style.css` as well as `/file/javascripts/jquery.js`. Wildcards are unnamed, so the matched value is available as `req.params[0]` instead of a named parameter. + +```js +app.get('/file/*', (req, res) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/file/*', (req: Request, res: Response) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + ### Caminho baseado em expressões regulares @@ -348,6 +368,14 @@ com uma barra invertida adicional, por exemplo `\d+`. The [`*`](https://github.com/expressjs/express/issues/2495) character in regular expressions is not interpreted in the usual way. Como uma alternativa, use `{0,}` em vez de `*`. +Unlike named route parameters, wildcard (`*`) matches in [string patterns](#route-paths-based-on-string-patterns) and capture groups in regular expressions are unnamed: their values are available by position, as `req.params[0]`, `req.params[1]`, and so on. + +``` +Route path: /file/*/size/* +Request URL: http://localhost:3000/file/javascripts/jquery.js/size/large +req.params: { "0": "javascripts/jquery.js", "1": "large" } +``` + ## Manipuladores de rota Você pode fornecer várias funções de retorno de chamada que se comportam como [middleware](/guide/using-middleware) para lidar com uma solicitação. A única exceção é que esses callbacks podem invocar `next('route')` para ignorar as chamadas restantes da rota. Você pode usar este mecanismo para impor pré-condições em uma rota, então passe controle para rotas subsequentes se não houver motivo para prosseguir com a rota atual. @@ -387,7 +415,7 @@ Neste exemplo: Os manipuladores de rotas podem estar na forma de uma função, um array de funções ou combinações de ambos, como mostrado nos exemplos a seguir. -Uma única função de retorno de chamada pode manipular uma rota. Por exemplo: +Mais de uma função de retorno de chamada pode manipular uma rota (certifique-se de especificar o objeto `next`). Por exemplo: ```js app.get('/example/a', (req, res) => { @@ -403,7 +431,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -Mais de uma função de retorno de chamada pode manipular uma rota (certifique-se de especificar o objeto `next`). Por exemplo: +Uma combinação de funções independentes e matrizes de funções pode lidar com uma rota. Por exemplo: ```js app.get( @@ -527,7 +555,7 @@ app.get( ## Métodos de resposta -Os métodos no objeto de resposta ('res') na tabela a seguir podem enviar uma resposta para o cliente e encerrar o ciclo de resposta de solicitação. Se nenhum destes métodos for chamado de um manipulador de redes, a solicitação do cliente será deixada em suspenso. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. Se nenhum destes métodos for chamado de um manipulador de redes, a solicitação do cliente será deixada em suspenso.| Method | Description | Método | Descrição: | | ----------------------------------------------- | --------------------------------------------------------------------------------------------------- | @@ -544,7 +572,7 @@ Os métodos no objeto de resposta ('res') na tabela a seguir podem enviar uma re ## app.route() Você pode criar manipuladores de rotas em cadeia para um caminho de rota usando `app.route()`. -Como o caminho é especificado em um único local, é útil criar rotas modulares, assim como reduzir a redundância e os tipos. Para obter mais informações sobre rotas, consulte: [documentação de roteador](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router). Aqui está um exemplo de manipuladores de rota encadeados que são definidos usando `app.route()`. @@ -580,9 +608,9 @@ app ## express.Router -Use a classe 'express.Router' para criar módulo, manipuladores de rotas montáveis. Uma instância `Router` é um sistema completo de middleware e roteamento; por este motivo, é muitas vezes referido como um "mini-app". +Use a classe 'express.Router' para criar módulo, manipuladores de rotas montáveis. Uma instância `Router` é um sistema completo de middleware e roteamento; por este motivo, é muitas vezes referido como um "mini-app".The following example creates a router as a module, loads a middlew -O exemplo a seguir cria um roteador como um módulo, carrega uma função middleware nele define algumas rotas e monta o módulo do roteador em um caminho no aplicativo principal. +O exemplo a seguir cria um roteador como um módulo, carrega uma função middleware nele define algumas rotas e monta o módulo do roteador em um caminho no aplicativo principal.Create a router file named `birds.js` in the app directory, with th Crie um arquivo de roteador chamado `birds.js` no diretório de aplicativos, com o seguinte conteúdo: @@ -677,7 +705,7 @@ app.use('/birds', birds); O aplicativo agora poderá lidar com pedidos para `/birds` e `/birds/about`, Além de chamar a função middleware `timeLog` que é específica da rota. -Mas se a rota pai `/birds` tiver parâmetros de caminho, ela não será acessível por padrão nas sub-rotas. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +Mas se a rota pai `/birds` tiver parâmetros de caminho, ela não será acessível por padrão nas sub-rotas. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter). ```js const router = express.Router({ mergeParams: true }); diff --git a/src/content/docs/pt-br/4x/guide/using-middleware.mdx b/src/content/docs/pt-br/4x/guide/using-middleware.mdx index 3e6e538e7f..5758981186 100644 --- a/src/content/docs/pt-br/4x/guide/using-middleware.mdx +++ b/src/content/docs/pt-br/4x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Aprenda a usar o middleware em aplicativos do Express.js, incluindo import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express é uma web framework de roteamento e middleware que tem a funcionalidade mínima de sua própria funcionalidade: Um aplicativo Express é essencialmente uma série de chamadas de função middleware. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -Middleware\_ são funções que têm acesso ao [objeto de requisição](/api#req) (`req`), a [objeto de resposta](/api#res) (`res`) e a próxima função de middleware no ciclo de resposta de solicitação do aplicativo. A próxima função de middleware é comumente denotada por uma variável chamada `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` As funções do Middleware podem executar as seguintes tarefas: - Execute qualquer código. -- Fazer alterações na solicitação e nos objetos de resposta. +- Modify the request and response objects. - Encerrar o ciclo de solicitação-resposta. -- Chame a próxima função middleware na pilha. +- Pass control to the next middleware function. -Se a função middleware atual não encerra o ciclo de resposta de solicitação, ela deve chamar `next()` para passar o controle para a próxima função middleware. Caso contrário, o pedido ficará pendurado. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Caso contrário, o pedido ficará pendurado. Um aplicativo Express pode usar os seguintes tipos de middleware: @@ -27,14 +32,15 @@ Um aplicativo Express pode usar os seguintes tipos de middleware: - [middleware](#middleware.built-in) - [Middleware de terceiros](#middleware.third-party) -Você pode carregar o nível de aplicação e middleware de nível de roteador com um caminho de montagem opcional. -Você também pode carregar uma série de funções intermediárias juntas, o que cria uma sub-pilha do sistema intermediário em um ponto de montagem. +Você pode carregar o nível de aplicação e middleware de nível de roteador com um caminho de montagem opcional. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Midddleware no nível de aplicação -Vincular aplicativo de nível middleware a uma instância do [objeto de aplicativo](/api#app) usando o `app.use()` e `app. Funções ETHOD()`, onde `METHOD` é o método HTTP da solicitação que a função middleware lida (como GET, PUT, ou POST) em minúsculas. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -Este exemplo mostra uma função middleware sem caminho de montagem. A função é executada toda vez que o aplicativo recebe uma solicitação. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -Este exemplo mostra uma função middleware montada no caminho `/user/:id`. A função é executada para qualquer tipo de solicitação HTTP -no caminho `/user/:id`. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Manipuladores de rota + Este exemplo mostra uma rota e sua função de manipulador (sistema de middleware). A função lida com requisições GET para o caminho `/user/:id`. ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Aqui está um exemplo de carregar uma série de funções intermediárias em um ponto de montagem, com um caminho de montagem. -Isto ilustra um sub-stack de middleware que imprime informação de solicitação para qualquer tipo de solicitação de HTTP no caminho `/user/:id`. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Os gerenciadores de rotas permitem que você defina várias rotas para um caminho. O exemplo abaixo define duas rotas para solicitações GET para o caminho `/user/:id`. A segunda via não causará quaisquer problemas, mas nunca será chamada, porque a primeira via termina o ciclo de resposta aos pedidos. +### Multiple route handlers -Este exemplo mostra uma sub-pilha de middleware que lida com requisições GET para o caminho `/user/:id`. +Os gerenciadores de rotas permitem que você defina várias rotas para um caminho. O exemplo abaixo define duas rotas para solicitações GET para o caminho `/user/:id`. A segunda via não causará quaisquer problemas, mas nunca será chamada, porque a primeira via termina o ciclo de resposta aos pedidos. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -Para ignorar o resto das funções de middleware a partir de uma pilha de middleware do roteador, chame `next('route')` para passar o controle para a próxima rota. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ Para ignorar o resto das funções de middleware a partir de uma pilha de middle -Este exemplo mostra uma sub-pilha de middleware que lida com requisições GET para o caminho `/user/:id`. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -O Middleware também pode ser declarado em um array para reutilizabilidade. +### Reusable middleware arrays -Este exemplo mostra um array com um sub-stack de middleware que lida com requisições GET para o caminho `/user/:id` +Middleware functions can also be grouped into arrays for better reusability. Este exemplo mostra um array com um sub-stack de middleware que lida com requisições GET para o caminho `/user/:id` ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,19 +280,25 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Midddleware nível de roteamento -O middleware de roteador funciona da mesma maneira que o middleware no nível de aplicativo, exceto que está vinculado a uma instância de `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); ``` +```ts +import express from 'express'; + +const router = express.Router(); +``` + Carregue o middleware no nível de roteador usando as funções `router.use()` e `router.METHOD()`. O código a seguir replica o sistema middleware que é mostrado acima para o middleware no nível de aplicativos, usando o middleware no nível de roteador: @@ -313,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -363,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -413,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -434,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -Para ignorar o resto das funções de middleware do roteador, chame `next('router')` -para passar o controle de volta para fora da instância do roteador. +### Skipping out of a router -Este exemplo mostra uma sub-pilha de middleware que lida com requisições GET para o caminho `/user/:id`. +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. + +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -506,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Midddleware com erro manipulado - - -O middleware com erros de manipulação sempre toma _quatro_ argumentos. Você deve fornecer quatro argumentos para -identificá-lo como uma função de middleware manipulação de erros. Mesmo se você não precisar usar o objeto `next` -, você deve especificá-lo para manter a assinatura. Caso contrário, o objeto `próximo` será -interpretado como um middleware regular e irá falhar em lidar com erros. - - - Definir funções intermediárias de manipulação de erros da mesma forma que outras funções de middleware, exceto quatro argumentos em vez de três, especificamente com a assinatura `(err, req, res, next)`: ```js @@ -533,7 +543,20 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Para detalhes sobre o middleware, consulte: [Error handling](/guide/error-handling). + + +O middleware com erros de manipulação sempre toma _quatro_ argumentos. Você deve fornecer quatro argumentos para +identificá-lo como uma função de middleware manipulação de erros. Mesmo se você não precisar usar o objeto `next` +, você deve especificá-lo para manter a assinatura. Caso contrário, o objeto `próximo` será +interpretado como um middleware regular e irá falhar em lidar com erros. + + + + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Midddleware integrado @@ -544,6 +567,8 @@ O Express tem as seguintes funções de middleware incorporadas: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. - [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTA: Disponível com Expresso 4.16.0+** +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. **NOTE: Available with Express 4.17.0+** +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. **NOTE: Available with Express 4.17.0+** - [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTA: Disponível com Expresso 4.16.0+** ## Midddleware de terceiros @@ -585,4 +610,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Para uma lista parcial de funções intermediárias de terceiros que são comumente usadas com Express, veja: [middleware de terceiros](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/pt-br/4x/guide/using-template-engines.mdx b/src/content/docs/pt-br/4x/guide/using-template-engines.mdx index 03705b9ff0..1871b8a63a 100644 --- a/src/content/docs/pt-br/4x/guide/using-template-engines.mdx +++ b/src/content/docs/pt-br/4x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Usando mecanismos de template com o Express -description: Descubra como integrar e usar mecanismos de modelos como Pug, Handlebars, e EJS com Express.js para renderizar páginas HTML dinâmicas de forma eficiente. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ Um _motor de template_ permite que você use arquivos de template estáticos na variables in a template file with actual values, and transforms the template into an HTML file sent to the client. Esta abordagem torna mais fácil projetar uma página HTML. -O [gerador de aplicação Expressa](/starter/generator) usa [Pug](https://pugjs.org/api/getting-started.html) como seu padrão, mas também apoia [Handlebars](https://www.npmjs.com/package/handlebars), e [EJS](https://www.npmjs.com/package/ejs), entre outros. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, o diretório onde se localizam os arquivos de template. Ex: `app.set('views', './views')`. Isto é padrão para o diretório `views` no diretório raiz do aplicativo. - `ver engenho`, o mecanismo de modelos a ser usado. Por exemplo, para usar o motor de template Pug: `app.set('engenharia de visualização', 'pug')`. -Então instale o correspondente mecanismo de template do npm pacote; por exemplo, para instalar o Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ que `res.render()` chama para renderizar o código de template. Alguns motores de modelos não seguem esta convenção. A biblioteca [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) segue esta convenção mapeando todos os mecanismos de modelo populares de Node.js e, portanto, funciona perfeitamente dentro do Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/pt-br/4x/guide/writing-middleware.mdx b/src/content/docs/pt-br/4x/guide/writing-middleware.mdx index 433d2058f8..aaf9895f9c 100644 --- a/src/content/docs/pt-br/4x/guide/writing-middleware.mdx +++ b/src/content/docs/pt-br/4x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Aprenda a escrever funções de middleware personalizadas para apli --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Middleware\_ são funções que têm acesso ao [objeto de requisição](/api#req) (`req`), a [objeto de resposta](/api#res) (`res`) e a função `next` no ciclo de resposta de solicitação do aplicativo. A função `próxima` é uma função no roteador Expresso que, quando invocado, executa o intermediário sucedendo ao intermediário atual. @@ -199,8 +200,8 @@ A função middleware `myLogger` simplesmente imprime uma mensagem, então passa ### Tempo de solicitação de função Middleware -Em seguida, vamos criar uma função middleware chamada "requestTime" e adicionar uma propriedade chamada `requestTime` -ao objeto solicitado. +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -420,9 +421,13 @@ atual é um erro e pulará quaisquer funções que ainda não sejam de manipula -Como você tem acesso ao objeto de solicitação, o objeto de resposta, a próxima função de middleware na pilha, e todo o nó. s API, as possibilidades com funções de middleware são infinitas. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Para mais informações sobre Express middleware, veja: [Usando Express middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## middleware configurável diff --git a/src/content/docs/pt-br/4x/starter/basic-routing.mdx b/src/content/docs/pt-br/4x/starter/basic-routing.mdx index 52b429d9cb..ba7a7968b7 100644 --- a/src/content/docs/pt-br/4x/starter/basic-routing.mdx +++ b/src/content/docs/pt-br/4x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Aprenda os fundamentos do roteamento em aplicações Express.js, in --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ refere-se a determinar como uma aplicação responde a uma solicitação do cliente para um ponto final específico, que é um URI (ou caminho) e um método de requisição HTTP específico (GET, POST, e assim por diante). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -Para mais detalhes sobre roteamento, consulte o [guia de roteamento](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/pt-br/4x/starter/faq.mdx b/src/content/docs/pt-br/4x/starter/faq.mdx index a9fc0be167..7b8d795efa 100644 --- a/src/content/docs/pt-br/4x/starter/faq.mdx +++ b/src/content/docs/pt-br/4x/starter/faq.mdx @@ -3,6 +3,8 @@ title: Perguntas Frequentes description: Encontre respostas para perguntas frequentes sobre Express.js, incluindo tópicos sobre a estrutura do aplicativo, modelos, autenticação, mecanismos de modelo, tratamento de erros e muito mais. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## Como eu devo estruturar meu aplicativo? Não há uma resposta definitiva a esta questão. A resposta depende @@ -42,7 +44,11 @@ Para normalizar interfaces do motor de modelos e cache de cache, veja o projeto [consolidate.js](https://github.com/visionmedia/consolidate.js) para suporte. Motores de modelos não listados ainda podem suportar a assinatura Express. -Para obter mais informações, consulte [Usando mecanismos de modelo com Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## Como lidamos com 404 respostas? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Para obter mais informações, consulte [Manipulação de erro](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Como faço para tornar HTML simples? diff --git a/src/content/docs/pt-br/4x/starter/installing.mdx b/src/content/docs/pt-br/4x/starter/installing.mdx index 1942211a7e..b0f4e30601 100644 --- a/src/content/docs/pt-br/4x/starter/installing.mdx +++ b/src/content/docs/pt-br/4x/starter/installing.mdx @@ -78,7 +78,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/pt-br/4x/starter/static-files.mdx b/src/content/docs/pt-br/4x/starter/static-files.mdx index ccbcc4619c..8a7f3076b6 100644 --- a/src/content/docs/pt-br/4x/starter/static-files.mdx +++ b/src/content/docs/pt-br/4x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Entenda como servir arquivos estáticos como imagens, CSS e JavaScr --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Para servir arquivos estáticos como imagens, arquivos CSS e arquivos JavaScript, use a função `express.static` middleware embutida no Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + Para mais detalhes sobre a função `serve-static` e suas opções, consulte [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/pt-br/5x/guide/debugging.mdx b/src/content/docs/pt-br/5x/guide/debugging.mdx index 7570928696..5666a72cab 100644 --- a/src/content/docs/pt-br/5x/guide/debugging.mdx +++ b/src/content/docs/pt-br/5x/guide/debugging.mdx @@ -4,104 +4,218 @@ description: Aprenda a habilitar e usar logs de depuração nos aplicativos Expr --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -Para ver todos os logs internos usados no Express, defina a variável de ambiente `DEBUG` para -`express:*` ao iniciar seu aplicativo. +To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*,router,router:*` when launching your app. Routing is handled by the separate [router](https://github.com/pillarjs/router) package, so its logs live under the `router` namespace and are not included in `express:*`. ```bash -$ DEBUG=express:* node index.js +$ DEBUG=express:*,router,router:* node index.js ``` No Windows, use o comando correspondente. ```bash -> $env:DEBUG = "express:*"; node index.js +> $env:DEBUG = "express:*,router,router:*"; node index.js ``` -Executar este comando no aplicativo padrão gerado pelo [gerador expresso](/starter/generator) imprime a seguinte saída: +Running this command on a small app with a JSON body parser and a mounted router prints the following output: + +```cjs title="index.cjs" +const express = require('express'); + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` + +```mjs title="index.mjs" +import express from 'express'; + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` ```bash -$ DEBUG=express:* node ./bin/www - express:router:route new / +0ms - express:router:layer new / +1ms - express:router:route get / +1ms - express:router:layer new / +0ms - express:router:route new / +1ms - express:router:layer new / +0ms - express:router:route get / +0ms - express:router:layer new / +0ms - express:application compile etag weak +1ms - express:application compile query parser extended +0ms - express:application compile trust proxy false +0ms - express:application booting in development mode +1ms - express:router use / query +0ms - express:router:layer new / +0ms - express:router use / expressInit +0ms - express:router:layer new / +0ms - express:router use / favicon +1ms - express:router:layer new / +0ms - express:router use / logger +0ms - express:router:layer new / +0ms - express:router use / jsonParser +0ms - express:router:layer new / +1ms - express:router use / urlencodedParser +0ms - express:router:layer new / +0ms - express:router use / cookieParser +0ms - express:router:layer new / +0ms - express:router use / stylus +90ms - express:router:layer new / +0ms - express:router use / serveStatic +0ms - express:router:layer new / +0ms - express:router use / router +0ms - express:router:layer new / +1ms - express:router use /users router +0ms - express:router:layer new /users +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms +$ DEBUG=express:*,router,router:* node index.js + express:application set "x-powered-by" to true +0ms + express:application set "etag" to 'weak' +3ms + express:application set "etag fn" to [Function: generateETag] +0ms + express:application set "env" to 'development' +1ms + express:application set "query parser" to 'simple' +0ms + express:application set "query parser fn" to [Function: parse] +0ms + express:application set "subdomain offset" to 2 +1ms + express:application set "trust proxy" to false +0ms + express:application set "trust proxy fn" to [Function: trustNone] +1ms + express:application booting in development mode +0ms + express:application set "view" to [Function: View] +0ms + express:application set "views" to '/projects/example/views' +1ms + express:application set "jsonp callback name" to 'callback' +0ms + router use '/' jsonParser +0ms + router:layer new '/' +0ms + router:route new '/' +0ms + router:layer new '/' +3ms + router:route get / +0ms + router:layer new '/' +1ms + router use '/users' router +4ms + router:layer new '/users' +0ms + router:route new '/' +1ms + router:layer new '/' +0ms + router:route get / +1ms + router:layer new '/' +1ms ``` Quando um pedido for feito ao aplicativo, você verá os logs especificados no código Expresso: ```bash - express:router dispatching GET / +4h - express:router query : / +2ms - express:router expressInit : / +0ms - express:router favicon : / +0ms - express:router logger : / +1ms - express:router jsonParser : / +0ms - express:router urlencodedParser : / +1ms - express:router cookieParser : / +0ms - express:router stylus : / +0ms - express:router serveStatic : / +2ms - express:router router : / +2ms - express:router dispatching GET / +1ms - express:view lookup "index.pug" +338ms - express:view stat "/projects/example/views/index.pug" +0ms - express:view render "/projects/example/views/index.pug" +1ms + router dispatching GET /users +712ms + router jsonParser : /users +1ms + router trim prefix (/users) from url /users +2ms + router router /users : /users +0ms + router dispatching GET / +0ms +``` + +To see the logs only from the router implementation, set the value of `DEBUG` to `router,router:*`. Da mesma forma, para ver apenas os logs da implementação do aplicativo, defina o valor de `DEBUG` para `express:application`, e assim por diante. + +## Using `debug` in your own code + +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: + + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); ``` -Para ver os logs apenas da implementação do roteador, defina o valor de `DEBUG` para `express:router`. Da mesma forma, para ver apenas os logs da implementação do aplicativo, defina o valor de `DEBUG` para `express:application`, e assim por diante. +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; -## Aplicações geradas por `express` +const debug = debugModule('myapp:server'); +const app = express(); -Uma aplicação gerada pelo comando `express` usa o módulo `debug` e seu namespace de depuração é escopo para o nome da aplicação. +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); -Por exemplo, se você gerou o app com `$ express sample-app`, você pode ativar as instruções de depuração com o seguinte comando: +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` Você pode especificar mais de um namespace de depuração atribuindo uma lista de nomes separada por vírgulas: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,router node index.js ``` +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*,router,router:*" } +} +``` + +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Opções avançadas Ao executar através do Node.js, você pode definir algumas variáveis de ambiente que irão mudar o comportamento do log de depuração: diff --git a/src/content/docs/pt-br/5x/guide/error-handling.mdx b/src/content/docs/pt-br/5x/guide/error-handling.mdx index ae7209b024..b9e467bd0f 100644 --- a/src/content/docs/pt-br/5x/guide/error-handling.mdx +++ b/src/content/docs/pt-br/5x/guide/error-handling.mdx @@ -14,6 +14,8 @@ manipulador para que você não precise escrever seu próprio para começar. É importante garantir que Expresso pegue todos os erros que ocorrem enquanto rodando manipuladores de rotas e intermediários. +### Errors in synchronous code + Erros que ocorrem no código síncrono dentro dos manipuladores de rota e middleware não exigem trabalho extra. If synchronous code throws an error, then Express will catch and process it. Por exemplo: @@ -32,51 +34,24 @@ app.get('/', (req: Request, res: Response) => { }); ``` -Para erros retornados de funções assíncronas, invocados pelos manipuladores de rota -e intermediário, você deve passá-los para a função `next()`, onde o Express irá capturá-los a -e processá-los. Por exemplo: - -```js -app.get('/', (req, res, next) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` +### Errors in asynchronous code -```ts -import { type Request, type Response, type NextFunction } from 'express'; - -app.get('/', (req: Request, res: Response, next: NextFunction) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` - -Começando pelo Express 5, roteadores e intermediários que retornam um Promise -chamarão `next(value)` automaticamente quando eles rejeitarem ou lançarem um erro. -Por exemplo: +The recommended way to write asynchronous handlers is with `async` functions. +Route handlers and middleware that return a Promise call `next(value)` +automatically when they reject or throw an error, and `async` functions always +return a Promise, so their errors reach Express with no extra work. Por exemplo: ```js -app.get('/user/:id', async (req, res, next) => { +app.get('/user/:id', async (req, res) => { const user = await getUserById(req.params.id); res.send(user); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', async (req: Request, res: Response) => { const user = await getUserById(req.params.id); res.send(user); }); @@ -90,49 +65,41 @@ Se você passar qualquer coisa para a função `next()` (exceto a string `'route Expressa que a requisição atual é um erro e irá pular quaisquer funções restantes que não sejam de manipulação de erros e middleware. -Se o callback em uma sequência não fornecer dados, somente erros, você pode simplificar -este código da seguinte forma: +### Working with promise chains + +If you build a promise chain instead of using an `async` function, return the +promise from the handler and Express will likewise call `next` automatically +when it rejects: ```js -app.get('/', [ - function (req, res, next) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req, res) { - res.send('OK'); - }, -]); +app.get('/', (req, res) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/', [ - function (req: Request, res: Response, next: NextFunction) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req: Request, res: Response) { - res.send('OK'); - }, -]); +app.get('/', (req: Request, res: Response) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` -No exemplo acima, `next` é fornecido como o callback para `fs.writeFile`, -que é chamado com ou sem erros. Se não houver erro, o segundo receptor -é executado, caso contrário as pegadas do Express e processa o erro. - -Você deve capturar os erros que ocorrem em código assíncrono invocado pelos manipuladores da rota ou -middleware e passá-los para o Expresso para processamento. Por exemplo: +If the promise is not returned, Express does not know it exists, and you must +route the error yourself by providing `next` as the final catch handler. +Without it, the rejection would be unhandled and crash the process: ```js app.get('/', (req, res, next) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` @@ -140,31 +107,32 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` -O exemplo acima usa um bloco `tentar... catch` para capturar erros no código assíncrono -e passá-los para o Express. Se o bloco `tentar...catch` -fosse omitido, Express não pegaria o erro, uma vez que ele não faz parte do código de manipulador -síncrono. +This works because if a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, `.catch` calls its handler with the error as the first argument, which is exactly the argument `next` expects, so the error reaches Express. -Você também pode usar uma cadeia de manipuladores para confiar em erro síncrono -de recuperação, reduzindo o código assíncrono a algo trivial. Por exemplo: +### Working with callback APIs + +Errors produced by callback-based APIs, such as those in `node:fs`, are not +thrown and are not part of any promise. The callback receives them as its first +argument, and you must pass them to the `next()` function yourself, where +Express will catch and process them. Por exemplo: ```js app.get('/', (req, res, next) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` @@ -172,17 +140,46 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` -Since promises automatically catch both synchronous errors and rejected promises, -you can simply provide `next` as the final catch handler and Express will catch errors, -because the catch handler is given the error as the first argument. +Se o callback em uma sequência não fornecer dados, somente erros, você pode simplificar +este código da seguinte forma: + +```js +app.get('/', [ + function (req, res, next) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req, res) { + res.send('OK'); + }, +]); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', [ + function (req: Request, res: Response, next: NextFunction) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req: Request, res: Response) { + res.send('OK'); + }, +]); +``` + +No exemplo acima, `next` é fornecido como o callback para `fs.writeFile`, +que é chamado com ou sem erros. Se não houver erro, o segundo receptor +é executado, caso contrário as pegadas do Express e processa o erro. Se você tiver um gerenciador de rotas com múltiplas funções de retorno de chamada, você pode usar o parâmetro `rota` para pular para o próximo manipulador de rota. Por exemplo: @@ -218,14 +215,49 @@ app.get('/', [ ]); ``` -O exemplo acima tem algumas declarações triviais da chamada `readFile` -. If `readFile` causes an error, then it passes the error to Express, otherwise you +The above example contains a couple of trivial statements following the `readFile` +call. If `readFile` causes an error, then it passes the error to Express, otherwise you quickly return to the world of synchronous error handling in the next handler in the chain. Então, o exemplo acima tenta processar os dados. Se isso falhar, o manipulador de erro síncrono irá pegá-lo. Se você tivesse feito este processamento dentro do o callback `readFile`, então o aplicativo poderia sair e o erro Express manipuladores não executariam. +Finally, for asynchronous code that provides no error-first callback, such as a +timer, catch errors inside the asynchronous code itself and pass them to +Express: + +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', (req: Request, res: Response, next: NextFunction) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +O exemplo acima usa um bloco `tentar... catch` para capturar erros no código assíncrono +e passá-los para o Express. Se o bloco `tentar...catch` +fosse omitido, Express não pegaria o erro, uma vez que ele não faz parte do código de manipulador +síncrono. + Seja qual for o método que você usar, se você quer que os manipuladores de erro Expressos sejam chamados para dentro e o aplicativo para sobreviver, você deve garantir que o Expresso receba o erro. @@ -423,7 +455,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Também neste exemplo, `clientErrorHandler` é definido como segue; neste caso, o erro é explicitamente passado para o próximo. -Observe que quando _não_ estiver chamando "próximo" em uma função de manipulação de erros, você é responsável por escrever (e terminar) a resposta. Caso contrário, esses pedidos ficarão "pendentes" e não serão elegíveis para a recolha de lixo. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Caso contrário, esses pedidos ficarão "pendentes" e não serão elegíveis para a recolha de lixo. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/pt-br/5x/guide/overriding-express-api.mdx b/src/content/docs/pt-br/5x/guide/overriding-express-api.mdx index be37b5c875..a9a483bf97 100644 --- a/src/content/docs/pt-br/5x/guide/overriding-express-api.mdx +++ b/src/content/docs/pt-br/5x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -A API do Expresso consiste de vários métodos e propriedades nos objetos de solicitação e resposta. Estas são herdadas pelo protótipo. Há dois pontos de extensão para a API Express: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. Estas são herdadas pelo protótipo. Há dois pontos de extensão para a API Express: 1. Os protótipos globais em `express.request` e `express.response`. 2. Protótipos específicos de aplicativo em `app.request` e `app.response`. diff --git a/src/content/docs/pt-br/5x/guide/routing.mdx b/src/content/docs/pt-br/5x/guide/routing.mdx index da716a6e1f..575e7d0569 100644 --- a/src/content/docs/pt-br/5x/guide/routing.mdx +++ b/src/content/docs/pt-br/5x/guide/routing.mdx @@ -13,7 +13,7 @@ por exemplo, `app. et()` para lidar com solicitações GET e `app.post` para lid see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. Em outras palavras, o aplicativo "listas" para solicitações que correspondem com a(s) rota(s) e método(s) especificado(s), e quando ela detecta uma correspondência, ela chama a função de retorno de chamada especificado. +Em outras palavras, o aplicativo "listas" para solicitações que correspondem com a(s) rota(s) e método(s) especificado(s), e quando ela detecta uma correspondência, ela chama a função de retorno de chamada especificado. Em outras palavras, o aplicativo "listas" para solicitações que correspondem com a(s) rota(s) e método(s) especificado(s), e quando ela detecta uma correspondência, ela chama a função de retorno de chamada especificado. Na verdade, os métodos de roteamento podem ter mais de uma função de callback como argumentos. Com múltiplas funções de callback, é importante fornecer `next` como um argumento para a função de callback e então chamar `next()` dentro do corpo da função para liberar o controle @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Expresso suporta métodos que correspondem a todos os métodos de requisição HTTP: `get`, `post`, e assim por diante. For a full list, see [app.METHOD](/api/application#appmethod). -Há um método de roteamento especial, `app.all()`, usado para carregar funções de middleware em um caminho para os métodos de requisição HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +Há um método de roteamento especial, `app.all()`, usado para carregar funções de middleware em um caminho para os métodos de requisição HTTP. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Caminho da rota -Roteamento, em combinação com um método de solicitação, defina os pontos de extremidade em que as solicitações podem ser feitas. Caminhos de rota podem ser strings ou expressões regulares. +Roteamento, em combinação com um método de solicitação, defina os pontos de extremidade em que as solicitações podem ser feitas. Caminhos de rota podem ser strings ou expressões regulares. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -153,77 +153,9 @@ app.get('/random.text', (req: Request, res: Response) => { }); ``` -### Wildcards - -Caracteres curinga correspondem a qualquer caminho após um prefixo. Eles devem ter um nome, assim como os parâmetros de rota, e são capturados como matrizes dos segmentos de caminho. - -```js -app.get('/files/*filepath', (req, res) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -Para também coincidir com o caminho raiz, envolva o caractere curinga nos chaves: - -```js -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req, res) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req: Request, res: Response) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -### Segmentos opcionais - -Use chaves para definir segmentos opcionais em um caminho de rota. Quando o segmento não está presente, o parâmetro é omitido de `req.params`. - -```js -app.get('/:file{.:ext}', (req, res) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/:file{.:ext}', (req: Request, res: Response) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -Os caracteres `?`, `+`, `*`, `[]`, and `()` são reservados e não podem ser usados como caracteres literais nos caminhos da rota. Use `\` para escapar deles se necessário. +The characters `?`, `+`, `*`, `[]`, `()`, and `!` are reserved and cannot be used as literal characters in route paths, and braces are reserved for [optional segments](#optional-segments). Use `\` para escapar deles se necessário. @@ -259,7 +191,11 @@ app.get(/.*fly$/, (req: Request, res: Response) => { ## Parâmetros de rota -Parâmetros de rota são denominados segmentos de URL que são usados para capturar os valores especificados em sua posição na URL. Os valores capturados são preenchidos no objeto `req.params`, com o nome do parâmetro de rota especificado no caminho como suas respectivas chaves. +Parâmetros de rota são denominados segmentos de URL que são usados para capturar os valores especificados em sua posição na URL. Os valores capturados são preenchidos no objeto `req.params`, com o nome do parâmetro de rota especificado no caminho como suas respectivas chaves. They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces. + +### Named parameters + +Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below. ``` Route path: /users/:userId/books/:bookId @@ -293,7 +229,7 @@ app.get('/users/:userId/books/:bookId', sendParams); -O nome dos parâmetros de rota deve ser composto de "palavra caracteres" ([A-Za-z0-9_]). +The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example `:"user-name"`. @@ -313,14 +249,122 @@ req.params: { "genus": "Prunus", "species": "persica" } -Caracteres Regexp não são suportados nos caminhos da rota. Use uma matriz de caminhos ou expressões regulares em vez disso. +Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as `:userId(\d+)`. Use an array of paths or a full regular expression instead. Veja a [sintaxe correspondente à trajetória](/guide/migrating-5#path-syntax) para obter mais informações. +### Wildcards + +Caracteres curinga correspondem a qualquer caminho após um prefixo. Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string. + +```js +app.get('/files/*filepath', (req, res) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +Para também coincidir com o caminho raiz, envolva o caractere curinga nos chaves: + +```js +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req, res) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req: Request, res: Response) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +### Segmentos opcionais + +Use chaves para definir segmentos opcionais em um caminho de rota. Quando o segmento não está presente, o parâmetro é omitido de `req.params`. + +```js +app.get('/:file{.:ext}', (req, res) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/:file{.:ext}', (req: Request, res: Response) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters: + +```js +app.get('/user/\{:id}', (req, res) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req, res) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/user/\{:id}', (req: Request, res: Response) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req: Request, res: Response) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +Não confunda a posição da barra no caminho da rota com a [configuração `strict routing`](/api/application/#application-settings), que diz respeito à URL da requisição: ela controla se uma URL terminada em barra que o caminho da rota não exige ainda corresponde. Por exemplo, uma requisição para `/order/` corresponde à rota `/order{/:id}` por padrão, mas retorna um erro 404 quando o strict routing está habilitado; a barra final de `/user/` não é afetada porque a rota `/user/\{:id}` a exige. Todas as requisições comentadas nos exemplos acima se comportam da mesma forma independentemente dessa configuração.## Route handlersYou can provide multiple callback functions that + ## Manipuladores de rota -Você pode fornecer várias funções de retorno de chamada que se comportam como [middleware](/guide/using-middleware) para lidar com uma solicitação. A única exceção é que esses callbacks podem invocar `next('route')` para ignorar as chamadas restantes da rota. Você pode usar este mecanismo para impor pré-condições em uma rota, então passe controle para rotas subsequentes se não houver motivo para prosseguir com a rota atual. +Você pode fornecer várias funções de retorno de chamada que se comportam como [middleware](/guide/using-middleware) para lidar com uma solicitação. A única exceção é que esses callbacks podem invocar `next('route')` para ignorar as chamadas restantes da rota. Você pode usar este mecanismo para impor pré-condições em uma rota, então passe controle para rotas subsequentes se não houver motivo para prosseguir com a rota atual.```js +app.get('/user/:id', (req, res, next) => { +if (req.params.i + +```` ```js app.get('/user/:id', (req, res, next) => { @@ -333,7 +377,7 @@ app.get('/user/:id', (req, res, next) => { app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0'); }); -``` +```` ```ts import { type Request, type Response, type NextFunction } from 'express'; @@ -355,15 +399,17 @@ Neste exemplo: - `GET /user/5` → tratado pela primeira rota → envia "Usuário 5" - `GET /user/0` → primeira rota chama `next('rote')`, pulando para a próxima rota `/user/:id` correspondente -Os manipuladores de rotas podem estar na forma de uma função, um array de funções ou combinações de ambos, como mostrado nos exemplos a seguir. +Os manipuladores de rotas podem estar na forma de uma função, um array de funções ou combinações de ambos, como mostrado nos exemplos a seguir.A single callback function can handle a route. For example:```js + +```` -Uma única função de retorno de chamada pode manipular uma rota. Por exemplo: +Mais de uma função de retorno de chamada pode manipular uma rota (certifique-se de especificar o objeto `next`). ```js app.get('/example/a', (req, res) => { res.send('Hello from A!'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -373,7 +419,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -Mais de uma função de retorno de chamada pode manipular uma rota (certifique-se de especificar o objeto `next`). Por exemplo: +Uma combinação de funções independentes e matrizes de funções pode lidar com uma rota. Por exemplo: ```js app.get( @@ -403,7 +449,7 @@ app.get( ); ``` -Um array de funções de retorno de chamada pode lidar com uma rota. Por exemplo: +Um array de funções de retorno de chamada pode lidar com uma rota. ```js const cb0 = function (req, res, next) { @@ -497,26 +543,32 @@ app.get( ## Métodos de resposta -Os métodos no objeto de resposta ('res') na tabela a seguir podem enviar uma resposta para o cliente e encerrar o ciclo de resposta de solicitação. Se nenhum destes métodos for chamado de um manipulador de redes, a solicitação do cliente será deixada em suspenso. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. Se nenhum destes métodos for chamado de um manipulador de redes, a solicitação do cliente será deixada em suspenso.| Method | Description| Method | Description -| Método | Descrição: | -| ----------------------------------------------- | --------------------------------------------------------------------------------------------------- | -| [res.download()](/api/response#resdownload) | Solicite que um arquivo seja baixado. | -| [res.end()](/api/response#resend) | Encerrar o processo de resposta. | -| [res.json()](/api/response#resjson) | Enviar uma resposta JSON. | -| [res.jsonp()](/api/response#resjsonp) | Envie uma resposta JSON com suporte a JSONP. | -| [res.redirect()](/api/response#resredirect) | Redirecionar uma requisição. | -| [res.render()](/api/response#resrender) | Renderizar um modelo de visão. | -| [res.send()](/api/response#ressend) | Envie uma resposta de vários tipos. | -| [res.sendFile()](/api/response#ressendfile) | Envia um arquivo como uma transmissão octet. | -| [res.sendStatus()](/api/response#ressendstatus) | Defina o código de status da resposta e envie sua representação de string como o corpo da resposta. | +| | | +| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/api/response#resdownload) | Solicite que um arquivo seja baixado. | +| [res.end()](/api/response#resend) | Encerrar o processo de resposta. | +| [res.json()](/api/response#resjson) | Enviar uma resposta JSON. | +| [res.jsonp()](/api/response#resjsonp) | Envie uma resposta JSON com suporte a JSONP. | +| | Redirecionar uma requisição. | +| [res.render()](/api/response#resrender) | Renderizar um modelo de visão. | +| [res.send()](/api/response#ressend) | Envie uma resposta de vários tipos. | +| [res.sendFile()](/api/response#ressendfile) | Envia um arquivo como uma transmissão octet. | +| [res.sendStatus()](/api/response#ressendstatus) | Defina o código de status da resposta e envie sua representação de string como o corpo da resposta. \|## app.route()You can create chainable route handlers for a rou | ## app.route() Você pode criar manipuladores de rotas em cadeia para um caminho de rota usando `app.route()`. -Como o caminho é especificado em um único local, é útil criar rotas modulares, assim como reduzir a redundância e os tipos. Para obter mais informações sobre rotas, consulte: [documentação de roteador](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router).Here is an example of chained route handlers that are defined by us + +Aqui está um exemplo de manipuladores de rota encadeados que são definidos usando `app.route()`.```js +app +.route('/book') +.get((req, res) => { +res.send('Ge -Aqui está um exemplo de manipuladores de rota encadeados que são definidos usando `app.route()`. +```` ```js app @@ -530,7 +582,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -550,9 +602,9 @@ app ## express.Router -Use a classe 'express.Router' para criar módulo, manipuladores de rotas montáveis. Uma instância `Router` é um sistema completo de middleware e roteamento; por este motivo, é muitas vezes referido como um "mini-app". +Use a classe 'express.Router' para criar módulo, manipuladores de rotas montáveis. Uma instância `Router` é um sistema completo de middleware e roteamento; por este motivo, é muitas vezes referido como um "mini-app".The following example creates a router as a module, loads a middlewThe following example creates a router as a module, loads a middlew -O exemplo a seguir cria um roteador como um módulo, carrega uma função middleware nele define algumas rotas e monta o módulo do roteador em um caminho no aplicativo principal. +O exemplo a seguir cria um roteador como um módulo, carrega uma função middleware nele define algumas rotas e monta o módulo do roteador em um caminho no aplicativo principal.Create a router file named `birds.js` in the app directory, with thCreate a router file named `birds.js` in the app directory, with th Crie um arquivo de roteador chamado `birds.js` no diretório de aplicativos, com o seguinte conteúdo: @@ -645,10 +697,13 @@ import birds from './birds'; app.use('/birds', birds); ``` -O aplicativo agora poderá lidar com pedidos para `/birds` e `/birds/about`, Além de chamar a função middleware `timeLog` que é específica da rota. +O aplicativo agora poderá lidar com pedidos para `/birds` e `/birds/about`, Além de chamar a função middleware `timeLog` que é específica da rota.But if the parent route `/birds` has path parameters, it will not b -Mas se a rota pai `/birds` tiver parâmetros de caminho, ela não será acessível por padrão nas sub-rotas. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +Mas se a rota pai `/birds` tiver parâmetros de caminho, ela não será acessível por padrão nas sub-rotas. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter).```js +const router = express.Router({ mergeParams: true }); + +```` ```js const router = express.Router({ mergeParams: true }); -``` +```` diff --git a/src/content/docs/pt-br/5x/guide/using-middleware.mdx b/src/content/docs/pt-br/5x/guide/using-middleware.mdx index 183cc486b8..bd105d229f 100644 --- a/src/content/docs/pt-br/5x/guide/using-middleware.mdx +++ b/src/content/docs/pt-br/5x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Aprenda a usar o middleware em aplicativos do Express.js, incluindo import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express é uma web framework de roteamento e middleware que tem a funcionalidade mínima de sua própria funcionalidade: Um aplicativo Express é essencialmente uma série de chamadas de função middleware. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -Middleware\_ são funções que têm acesso ao [objeto de requisição](/api#req) (`req`), a [objeto de resposta](/api#res) (`res`) e a próxima função de middleware no ciclo de resposta de solicitação do aplicativo. A próxima função de middleware é comumente denotada por uma variável chamada `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` As funções do Middleware podem executar as seguintes tarefas: - Execute qualquer código. -- Fazer alterações na solicitação e nos objetos de resposta. +- Modify the request and response objects. - Encerrar o ciclo de solicitação-resposta. -- Chame a próxima função middleware na pilha. +- Pass control to the next middleware function. -Se a função middleware atual não encerra o ciclo de resposta de solicitação, ela deve chamar `next()` para passar o controle para a próxima função middleware. Caso contrário, o pedido ficará pendurado. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Caso contrário, o pedido ficará pendurado. Um aplicativo Express pode usar os seguintes tipos de middleware: @@ -27,14 +32,15 @@ Um aplicativo Express pode usar os seguintes tipos de middleware: - [middleware](#middleware.built-in) - [Middleware de terceiros](#middleware.third-party) -Você pode carregar o nível de aplicação e middleware de nível de roteador com um caminho de montagem opcional. -Você também pode carregar uma série de funções intermediárias juntas, o que cria uma sub-pilha do sistema intermediário em um ponto de montagem. +Você pode carregar o nível de aplicação e middleware de nível de roteador com um caminho de montagem opcional. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Midddleware no nível de aplicação -Vincular aplicativo de nível middleware a uma instância do [objeto de aplicativo](/api#app) usando o `app.use()` e `app. Funções ETHOD()`, onde `METHOD` é o método HTTP da solicitação que a função middleware lida (como GET, PUT, ou POST) em minúsculas. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -Este exemplo mostra uma função middleware sem caminho de montagem. A função é executada toda vez que o aplicativo recebe uma solicitação. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -Este exemplo mostra uma função middleware montada no caminho `/user/:id`. A função é executada para qualquer tipo de solicitação HTTP -no caminho `/user/:id`. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Manipuladores de rota + Este exemplo mostra uma rota e sua função de manipulador (sistema de middleware). A função lida com requisições GET para o caminho `/user/:id`. ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Aqui está um exemplo de carregar uma série de funções intermediárias em um ponto de montagem, com um caminho de montagem. -Isto ilustra um sub-stack de middleware que imprime informação de solicitação para qualquer tipo de solicitação de HTTP no caminho `/user/:id`. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Os gerenciadores de rotas permitem que você defina várias rotas para um caminho. O exemplo abaixo define duas rotas para solicitações GET para o caminho `/user/:id`. A segunda via não causará quaisquer problemas, mas nunca será chamada, porque a primeira via termina o ciclo de resposta aos pedidos. +### Multiple route handlers -Este exemplo mostra uma sub-pilha de middleware que lida com requisições GET para o caminho `/user/:id`. +Os gerenciadores de rotas permitem que você defina várias rotas para um caminho. O exemplo abaixo define duas rotas para solicitações GET para o caminho `/user/:id`. A segunda via não causará quaisquer problemas, mas nunca será chamada, porque a primeira via termina o ciclo de resposta aos pedidos. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -Para ignorar o resto das funções de middleware a partir de uma pilha de middleware do roteador, chame `next('route')` para passar o controle para a próxima rota. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ Para ignorar o resto das funções de middleware a partir de uma pilha de middle -Este exemplo mostra uma sub-pilha de middleware que lida com requisições GET para o caminho `/user/:id`. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -O Middleware também pode ser declarado em um array para reutilizabilidade. +### Reusable middleware arrays -Este exemplo mostra um array com um sub-stack de middleware que lida com requisições GET para o caminho `/user/:id` +Middleware functions can also be grouped into arrays for better reusability. Este exemplo mostra um array com um sub-stack de middleware que lida com requisições GET para o caminho `/user/:id` ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,14 +280,14 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Midddleware nível de roteamento -O middleware de roteador funciona da mesma maneira que o middleware no nível de aplicativo, exceto que está vinculado a uma instância de `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); @@ -319,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -369,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -419,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -440,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -Para ignorar o resto das funções de middleware do roteador, chame `next('router')` -para passar o controle de volta para fora da instância do roteador. +### Skipping out of a router + +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. -Este exemplo mostra uma sub-pilha de middleware que lida com requisições GET para o caminho `/user/:id`. +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -512,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Midddleware com erro manipulado - - -O middleware com erros de manipulação sempre toma _quatro_ argumentos. Você deve fornecer quatro argumentos para -identificá-lo como uma função de middleware manipulação de erros. Mesmo se você não precisar usar o objeto `next` -, você deve especificá-lo para manter a assinatura. Caso contrário, o objeto `próximo` será -interpretado como um middleware regular e irá falhar em lidar com erros. - - - Definir funções intermediárias de manipulação de erros da mesma forma que outras funções de middleware, exceto quatro argumentos em vez de três, especificamente com a assinatura `(err, req, res, next)`: ```js @@ -539,18 +543,30 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Para detalhes sobre o middleware, consulte: [Error handling](/guide/error-handling). + -## Midddleware integrado +O middleware com erros de manipulação sempre toma _quatro_ argumentos. Você deve fornecer quatro argumentos para +identificá-lo como uma função de middleware manipulação de erros. Mesmo se você não precisar usar o objeto `next` +, você deve especificá-lo para manter a assinatura. Caso contrário, o objeto `próximo` será +interpretado como um middleware regular e irá falhar em lidar com erros. + + + + -A partir da versão 4.x, o Express não depende mais do [Connect](https://github.com/senchalabs/connect). O middleware -funções que foram previamente incluídas com Express estão agora em módulos separados; consulte [a lista de funções de middleware](https://github.com/senchalabs/connect#middleware). +For more information, see the [Error handling](/guide/error-handling) guide. + + + +## Midddleware integrado O Express tem as seguintes funções de middleware incorporadas: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. -- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTA: Disponível com Expresso 4.16.0+** -- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTA: Disponível com Expresso 4.16.0+** +- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. +- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. ## Midddleware de terceiros @@ -591,4 +607,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -Para uma lista parcial de funções intermediárias de terceiros que são comumente usadas com Express, veja: [middleware de terceiros](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/pt-br/5x/guide/using-template-engines.mdx b/src/content/docs/pt-br/5x/guide/using-template-engines.mdx index 03705b9ff0..1871b8a63a 100644 --- a/src/content/docs/pt-br/5x/guide/using-template-engines.mdx +++ b/src/content/docs/pt-br/5x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Usando mecanismos de template com o Express -description: Descubra como integrar e usar mecanismos de modelos como Pug, Handlebars, e EJS com Express.js para renderizar páginas HTML dinâmicas de forma eficiente. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ Um _motor de template_ permite que você use arquivos de template estáticos na variables in a template file with actual values, and transforms the template into an HTML file sent to the client. Esta abordagem torna mais fácil projetar uma página HTML. -O [gerador de aplicação Expressa](/starter/generator) usa [Pug](https://pugjs.org/api/getting-started.html) como seu padrão, mas também apoia [Handlebars](https://www.npmjs.com/package/handlebars), e [EJS](https://www.npmjs.com/package/ejs), entre outros. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, o diretório onde se localizam os arquivos de template. Ex: `app.set('views', './views')`. Isto é padrão para o diretório `views` no diretório raiz do aplicativo. - `ver engenho`, o mecanismo de modelos a ser usado. Por exemplo, para usar o motor de template Pug: `app.set('engenharia de visualização', 'pug')`. -Então instale o correspondente mecanismo de template do npm pacote; por exemplo, para instalar o Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ que `res.render()` chama para renderizar o código de template. Alguns motores de modelos não seguem esta convenção. A biblioteca [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) segue esta convenção mapeando todos os mecanismos de modelo populares de Node.js e, portanto, funciona perfeitamente dentro do Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/pt-br/5x/guide/writing-middleware.mdx b/src/content/docs/pt-br/5x/guide/writing-middleware.mdx index 6495b2897b..5b9649ad9f 100644 --- a/src/content/docs/pt-br/5x/guide/writing-middleware.mdx +++ b/src/content/docs/pt-br/5x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Aprenda a escrever funções de middleware personalizadas para apli --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Middleware\_ são funções que têm acesso ao [objeto de requisição](/api#req) (`req`), a [objeto de resposta](/api#res) (`res`) e a função `next` no ciclo de resposta de solicitação do aplicativo. A função `próxima` é uma função no roteador Expresso que, quando invocado, executa o intermediário sucedendo ao intermediário atual. @@ -170,8 +171,8 @@ A função middleware `myLogger` simplesmente imprime uma mensagem, então passa ### Tempo de solicitação de função Middleware -Em seguida, vamos criar uma função middleware chamada "requestTime" e adicionar uma propriedade chamada `requestTime` -ao objeto solicitado. +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -391,9 +392,13 @@ atual é um erro e pulará quaisquer funções que ainda não sejam de manipula -Como você tem acesso ao objeto de solicitação, o objeto de resposta, a próxima função de middleware na pilha, e todo o nó. s API, as possibilidades com funções de middleware são infinitas. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -Para mais informações sobre Express middleware, veja: [Usando Express middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## middleware configurável diff --git a/src/content/docs/pt-br/5x/starter/basic-routing.mdx b/src/content/docs/pt-br/5x/starter/basic-routing.mdx index 52b429d9cb..ba7a7968b7 100644 --- a/src/content/docs/pt-br/5x/starter/basic-routing.mdx +++ b/src/content/docs/pt-br/5x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Aprenda os fundamentos do roteamento em aplicações Express.js, in --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ refere-se a determinar como uma aplicação responde a uma solicitação do cliente para um ponto final específico, que é um URI (ou caminho) e um método de requisição HTTP específico (GET, POST, e assim por diante). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -Para mais detalhes sobre roteamento, consulte o [guia de roteamento](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/pt-br/5x/starter/faq.mdx b/src/content/docs/pt-br/5x/starter/faq.mdx index 3b1ca4efdb..39bc8e974c 100644 --- a/src/content/docs/pt-br/5x/starter/faq.mdx +++ b/src/content/docs/pt-br/5x/starter/faq.mdx @@ -3,6 +3,8 @@ title: Perguntas Frequentes description: Encontre respostas para perguntas frequentes sobre Express.js, incluindo tópicos sobre a estrutura do aplicativo, modelos, autenticação, mecanismos de modelo, tratamento de erros e muito mais. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## Como eu devo estruturar meu aplicativo? Não há uma resposta definitiva a esta questão. A resposta depende @@ -42,7 +44,11 @@ Para normalizar interfaces do motor de modelos e cache de cache, veja o projeto [consolidate.js](https://github.com/visionmedia/consolidate.js) para suporte. Motores de modelos não listados ainda podem suportar a assinatura Express. -Para obter mais informações, consulte [Usando mecanismos de modelo com Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## Como lidamos com 404 respostas? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -Para obter mais informações, consulte [Manipulação de erro](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Como faço para tornar HTML simples? diff --git a/src/content/docs/pt-br/5x/starter/installing.mdx b/src/content/docs/pt-br/5x/starter/installing.mdx index 0b7283d238..cf63b9e006 100644 --- a/src/content/docs/pt-br/5x/starter/installing.mdx +++ b/src/content/docs/pt-br/5x/starter/installing.mdx @@ -70,7 +70,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/pt-br/5x/starter/static-files.mdx b/src/content/docs/pt-br/5x/starter/static-files.mdx index ccbcc4619c..8a7f3076b6 100644 --- a/src/content/docs/pt-br/5x/starter/static-files.mdx +++ b/src/content/docs/pt-br/5x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Entenda como servir arquivos estáticos como imagens, CSS e JavaScr --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; Para servir arquivos estáticos como imagens, arquivos CSS e arquivos JavaScript, use a função `express.static` middleware embutida no Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + Para mais detalhes sobre a função `serve-static` e suas opções, consulte [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/zh-cn/4x/guide/debugging.mdx b/src/content/docs/zh-cn/4x/guide/debugging.mdx index beb9dc3f3b..5a94b6bc8b 100644 --- a/src/content/docs/zh-cn/4x/guide/debugging.mdx +++ b/src/content/docs/zh-cn/4x/guide/debugging.mdx @@ -4,6 +4,7 @@ description: 通过设置 DEBUG 环境变量来开启并使用 Express.js 应用 --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; 若要查看 Express 中使用的所有内部日志,请在启动应用时将 `DEBUG` 环境变量设置为 `express:*`。 @@ -85,22 +86,119 @@ $ DEBUG=express:* node ./bin/www 若仅查看来自路由实现的日志,请将 `DEBUG` 的值设置为 `express:router`。 同理,若仅查看来自应用实现的日志,请将 `DEBUG` 的值设置为 `express:application`,以此类推。 -## 由 `express` 生成的应用 +## Using `debug` in your own code -由 `express` 命令生成的应用会使用 `debug` 模块,且其调试命名空间的作用域限定为应用名称。 +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: -例如,如果你使用 `$ express sample-app` 命令生成了应用,可以通过以下命令启用调试语句: + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; + +const debug = debugModule('myapp:server'); +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` 你可以通过指定以英文逗号分隔的名称列表,来启用多个调试命名空间: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,express:router node index.js +``` + +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*" } +} ``` +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## 高级选项 在通过 Node.js 运行时,你可以设置若干环境变量来更改调试日志的行为: diff --git a/src/content/docs/zh-cn/4x/guide/error-handling.mdx b/src/content/docs/zh-cn/4x/guide/error-handling.mdx index 9a9d626e11..42b338b8ca 100644 --- a/src/content/docs/zh-cn/4x/guide/error-handling.mdx +++ b/src/content/docs/zh-cn/4x/guide/error-handling.mdx @@ -55,13 +55,16 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -从 Express 5 开始,返回 Promise 的路由处理程序和中间件在拒绝(reject)或抛出错误时,将自动调用 `next(value)`。 -举个例子: +Errors from rejected promises are not passed to `next` automatically, and this includes `async` functions: if an `async` route handler throws or awaits a rejected promise, the rejection is unhandled, which crashes the process on current Node.js versions. You must catch the error yourself and pass it to Express: ```js app.get('/user/:id', async (req, res, next) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` @@ -69,12 +72,22 @@ app.get('/user/:id', async (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` -如果 `getUserById` 抛出错误或被拒绝(reject),`next` 将会使用抛出的错误或被拒绝的值来调用。 如果未提供拒绝值,则会使用 Express 路由内置的默认错误对象调用 `next`。 + + +Consider [updating to Express 5](/guide/migrating-5), where route handlers and middleware that +return a Promise call `next(value)` automatically when they reject or throw an error, making the +`try...catch` above unnecessary. + + 如果向 `next()` 传入任意参数(字符串 `'route'` 除外),Express 会将当前请求视作出错,并跳过后续所有非错误处理的路由与中间件函数。 @@ -160,7 +173,7 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -由于 Promise 会自动捕获同步错误和被拒绝的 Promise,你只需将 `next` 作为最终的 catch 处理程序传入即可,Express 会捕获错误,因为 catch 处理程序会将错误作为第一个参数传入。 +If a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, passing `next` as the handler is enough: `.catch` calls it with the error as its first argument, which is exactly the argument `next` expects, so the error reaches Express. 你也可以使用处理程序链,将异步代码简化为简单逻辑,从而依靠同步错误捕获机制。 举个例子: @@ -196,7 +209,8 @@ app.get('/', [ ]); ``` -上述示例包含几条来自 `readFile` 调用的简单语句。 如果 `readFile` 引发错误,则会将错误传递给 Express;否则你将迅速回到处理程序链中下一个处理函数的同步错误处理流程。 然后,上述示例会尝试处理数据。 如果此过程失败,同步错误处理程序将会捕获该错误。 如果你将此处理逻辑写在 `readFile` 回调函数内部,应用程序可能会直接退出,Express 错误处理程序将无法执行。 +The above example contains a couple of trivial statements following the `readFile` +call. 如果 `readFile` 引发错误,则会将错误传递给 Express;否则你将迅速回到处理程序链中下一个处理函数的同步错误处理流程。 然后,上述示例会尝试处理数据。 如果此过程失败,同步错误处理程序将会捕获该错误。 如果你将此处理逻辑写在 `readFile` 回调函数内部,应用程序可能会直接退出,Express 错误处理程序将无法执行。 无论你使用哪种方法,若希望 Express 错误处理程序被调用且应用程序持续运行,必须确保 Express 能够接收到错误。 @@ -378,7 +392,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Also in this example, `clientErrorHandler` is defined as follows; in this case, the error is explicitly passed along to the next one. -Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/zh-cn/4x/guide/overriding-express-api.mdx b/src/content/docs/zh-cn/4x/guide/overriding-express-api.mdx index 6573560b24..6e87e07a63 100644 --- a/src/content/docs/zh-cn/4x/guide/overriding-express-api.mdx +++ b/src/content/docs/zh-cn/4x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -Express API 由请求对象和响应对象上的多种方法与属性组成。 这些内容通过原型继承。 Express API 有两个扩展点: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. 这些内容通过原型继承。 Express API 有两个扩展点: 1. `express.request` 和 `express.response` 上的全局原型。 2. 应用专属原型位于 `app.request` 和 `app.response`。 diff --git a/src/content/docs/zh-cn/4x/guide/routing.mdx b/src/content/docs/zh-cn/4x/guide/routing.mdx index 3cde7a4ca4..d71db87717 100644 --- a/src/content/docs/zh-cn/4x/guide/routing.mdx +++ b/src/content/docs/zh-cn/4x/guide/routing.mdx @@ -7,14 +7,16 @@ import Alert from '@components/primitives/Alert/Alert.astro'; **路由**是指应用程序的端点(URI)如何响应客户端的请求。 For an introduction to routing, see [Basic routing](/starter/basic-routing). +For an introduction to routing, see [Basic routing](/starter/basic-routing). 你可以使用 Express `app` 对象中与 HTTP 方法对应的方法来定义路由; 例如,`app.get()` 处理 GET 请求,`app.post` 处理 POST 请求。 For a full list, see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. 换句话说,应用程序会“监听”匹配指定路由和方法的请求,当检测到匹配时,就会调用指定的回调函数。 +换句话说,应用程序会“监听”匹配指定路由和方法的请求,当检测到匹配时,就会调用指定的回调函数。 These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. +事实上,路由方法可以接受多个回调函数作为参数。 事实上,路由方法可以接受多个回调函数作为参数。 对于多个回调函数,务必在回调函数中传入`next`作为参数,然后在函数体内调用`next()`,将控制权传递给下一个回调函数。 @@ -84,10 +86,13 @@ app.post('/', (req: Request, res: Response) => { }); ``` -Express 支持对应于所有 HTTP 请求方法的方法:get、post 等。 -For a full list, see [app.METHOD](/api/application#appmethod). +你可以使用 Express `app` 对象中与 HTTP 方法对应的方法来定义路由; +例如,`app.get()` 处理 GET 请求,`app.post` 处理 POST 请求。 For a full list, +see [app.METHOD](/api/application#appmethod). +You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to +specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -有一种特殊的路由方法 **app.all()**,用于为某一路径加载所有 HTTP 请求方法通用的中间件函数。 For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +有一种特殊的路由方法 **app.all()**,用于为某一路径加载所有 HTTP 请求方法通用的中间件函数。 For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -107,7 +112,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Route paths -路由路径与请求方法结合,定义了可以接收请求的端点。 路由路径可以是字符串、字符串模式或正则表达式。 +路由路径与请求方法结合,定义了可以接收请求的端点。 路由路径可以是字符串、字符串模式或正则表达式。 路由路径与请求方法结合,定义了可以接收请求的端点。 路由路径可以是字符串或正则表达式。 They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -234,6 +239,26 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => { }); ``` +A wildcard (`*`) on its own matches anything at its position, including entire subpaths. For example, this route path will match `/file/style.css` as well as `/file/javascripts/jquery.js`. Wildcards are unnamed, so the matched value is available as `req.params[0]` instead of a named parameter. + +```js +app.get('/file/*', (req, res) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/file/*', (req: Request, res: Response) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + ### 基于正则表达式的路由路径 @@ -276,7 +301,7 @@ app.get(/.*fly$/, (req: Request, res: Response) => { ## Route parameters -路由参数是命名式URL片段,用于捕获URL中对应位置所指定的值。 捕获的值会存入`req.params`对象,路径中定义的路由参数名作为该对象对应的键名。 +路由参数是命名式URL片段,用于捕获URL中对应位置所指定的值。 捕获的值会存入`req.params`对象,路径中定义的路由参数名作为该对象对应的键名。 They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces. 捕获的值会存入`req.params`对象,路径中定义的路由参数名作为该对象对应的键名。 ``` Route path: /users/:userId/books/:bookId @@ -347,9 +372,17 @@ characters with an additional backslash, for example `\d+`. The [`*`](https://github.com/expressjs/express/issues/2495) character in regular expressions is not interpreted in the usual way. 作为替代方案,可用`{0,}`替代`*`。 +Unlike named route parameters, wildcard (`*`) matches in [string patterns](#route-paths-based-on-string-patterns) and capture groups in regular expressions are unnamed: their values are available by position, as `req.params[0]`, `req.params[1]`, and so on. + +``` +Route path: /file/*/size/* +Request URL: http://localhost:3000/file/javascripts/jquery.js/size/large +req.params: { "0": "javascripts/jquery.js", "1": "large" } +``` + ## Route handlers -You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. 唯一的例外是这些回调函数可以调用 `next('route')` 来跳过剩余的路由回调。 你可以通过这种机制为路由施加前置条件,如果没有理由继续执行当前路由,则将控制权传递给后续路由。 +You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. 唯一的例外是这些回调函数可以调用 `next('route')` 来跳过剩余的路由回调。 你可以通过这种机制为路由施加前置条件,如果没有理由继续执行当前路由,则将控制权传递给后续路由。 你可以通过这种机制为路由施加前置条件,如果没有理由继续执行当前路由,则将控制权传递给后续路由。 ```js app.get('/user/:id', (req, res, next) => { @@ -402,7 +435,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -多个回调函数可以处理同一个路由(请确保你指定了 `next` 对象)。 举个例子: +多个回调函数可以处理同一个路由(请确保你指定了 `next` 对象)。 举个例子: 举个例子: ```js app.get( @@ -526,7 +559,7 @@ app.get( ## Response methods -下表中的响应对象(`res`)方法可向客户端发送响应,并终止请求-响应循环。 如果路由处理程序未调用这些方法中的任何一个,客户端请求将一直处于挂起状态。 +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. 如果路由处理程序未调用这些方法中的任何一个,客户端请求将一直处于挂起状态。 | Method | 描述 | | ----------------------------------------------- | ---------------------------------------------------- | @@ -543,7 +576,8 @@ app.get( ## app.route() 你可以使用 `app.route()` 为路由路径创建可链式调用的路由处理程序。 -由于路径在单个位置指定,因此创建模块化路由十分有用,同时还能减少冗余和拼写错误。 For more information about routes, see: [Router() documentation](/api/router). +你可以使用 `app.route()` 为路由路径创建可链式调用的路由处理程序。 +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router). 以下是使用 `app.route()` 定义的链式路由处理程序示例。 @@ -579,9 +613,9 @@ app ## express.Router -使用 `express.Router` 类创建模块化、可挂载的路由处理程序。 `Router` 实例是一个完整的中间件和路由系统;因此,它通常被称为“迷你应用”。 +使用 `express.Router` 类创建模块化、可挂载的路由处理程序。 使用 `express.Router` 类创建模块化、可挂载的路由处理程序。 `Router` 实例是一个完整的中间件和路由系统;因此,它通常被称为“迷你应用”。The following example creates a router as a module, loads a middlew -以下示例创建一个路由模块,在其中加载中间件函数、定义若干路由,并将该路由模块挂载到主应用的指定路径上。 +以下示例创建一个路由模块,在其中加载中间件函数、定义若干路由,并将该路由模块挂载到主应用的指定路径上。Create a router file named `birds.js` in the app directory, with th 在应用目录中创建一个名为 `birds.js` 的路由文件,内容如下: @@ -676,7 +710,7 @@ app.use('/birds', birds); 应用现在将能够处理指向 `/birds` 和 `/birds/about` 的请求,同时会调用该路由专用的 `timeLog` 中间件函数。 -但如果父路由 `/birds` 包含路径参数,默认情况下子路由无法访问这些参数。 To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +但如果父路由 `/birds` 包含路径参数,默认情况下子路由无法访问这些参数。 但如果父路由 `/birds` 包含路径参数,默认情况下子路由无法访问这些参数。 To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter). ```js const router = express.Router({ mergeParams: true }); diff --git a/src/content/docs/zh-cn/4x/guide/using-middleware.mdx b/src/content/docs/zh-cn/4x/guide/using-middleware.mdx index 50cdd35621..f02d64d76f 100644 --- a/src/content/docs/zh-cn/4x/guide/using-middleware.mdx +++ b/src/content/docs/zh-cn/4x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: 了解如何在 Express.js 应用中使用中间件,包括应用 import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express 是一款路由与中间件 Web 框架,自身仅提供极简的基础功能:一个 Express 应用本质上就是一连串中间件函数的调用。 +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -_Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the next middleware function in the application's request-response cycle. 下一个中间件函数通常使用名为`next`的变量来表示。 +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` 中间件函数可执行下列任务: - 执行任意代码。 -- 修改请求对象与响应对象。 +- Modify the request and response objects. - 终止请求-响应周期。 -- 调用栈中的下一个中间件函数。 +- Pass control to the next middleware function. -如果当前中间件函数没有终止请求-响应周期,它必须调用 `next()` 以将控制权传递给下一个中间件函数。 否则,请求将会被挂起。 +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. 否则,请求将会被挂起。 Express 应用可以使用以下类型的中间件: @@ -27,14 +32,15 @@ Express 应用可以使用以下类型的中间件: - [Built-in middleware](#middleware.built-in) - [Third-party middleware](#middleware.third-party) -你可以通过可选的挂载路径加载应用级中间件和路由级中间件。 -你也可以同时加载一系列中间件函数,这会在挂载点处创建中间件系统的一个子栈。 +你可以通过可选的挂载路径加载应用级中间件和路由级中间件。 Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## 应用级中间件 -Bind application-level middleware to an instance of the [app object](/api#app) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -本示例展示了一个没有挂载路径的中间件函数。 每当应用接收请求时,该函数都会被执行。 +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,7 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -本示例展示了一个挂载在 `/user/:id` 路径上的中间件函数。 只要是发往 `/user/:id` 路径的任意类型 HTTP 请求,都会执行该中间件函数。 +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -86,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Route handlers + 该示例展示了一条路由及其处理函数(中间件体系)。 该函数处理指向 `/user/:id` 路径的 GET 请求。 ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -下面是在指定挂载路径的挂载点加载一系列中间件函数的示例。 -该示例演示了一个中间件子栈,会对所有访问 `/user/:id` 路径的各类 HTTP 请求打印请求信息。 +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -135,9 +146,9 @@ app.use( ); ``` -路由处理程序支持为同一个路径定义多条路由。 下面的示例为 `/user/:id` 路径的 GET 请求定义了两条路由。 第二条路由不会报错,但永远不会被执行,因为第一条路由已经结束了请求-响应周期。 +### Multiple route handlers -该示例展示了一个中间件子栈,用于处理 `/user/:id` 路径的 GET 请求。 +路由处理程序支持为同一个路径定义多条路由。 下面的示例为 `/user/:id` 路径的 GET 请求定义了两条路由。 第二条路由不会报错,但永远不会被执行,因为第一条路由已经结束了请求-响应周期。 ```js app.get( @@ -146,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -166,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -若要跳过路由中间件栈中剩余的中间件函数,调用 `next('route')` 即可将控制权传递给下一条路由。 +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -185,7 +198,7 @@ app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { -该示例展示了一个中间件子栈,用于处理 `/user/:id` 路径的 GET 请求。 +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -196,14 +209,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -219,21 +232,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -中间件也可以定义在数组中,实现复用。 +### Reusable middleware arrays -该示例展示了一个使用数组封装的中间件子栈,用于处理 `/user/:id` 路径的 GET 请求。 +Middleware functions can also be grouped into arrays for better reusability. 该示例展示了一个使用数组封装的中间件子栈,用于处理 `/user/:id` 路径的 GET 请求。 ```js function logOriginalUrl(req, res, next) { @@ -247,7 +260,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -266,19 +279,25 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## 路由级中间件 -路由级中间件的工作方式与应用级中间件完全相同,唯一区别是它绑定到 `express.Router()` 的实例上。 +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); ``` +```ts +import express from 'express'; + +const router = express.Router(); +``` + 通过 `router.use()` 和 `router.METHOD()` 函数加载路由级中间件。 下面的示例代码通过路由级中间件,复刻了上方展示的应用级中间件的中间件体系: @@ -311,19 +330,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -361,19 +380,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -411,19 +430,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -432,9 +451,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -若要跳过当前路由实例中剩余的中间件函数,调用 `next('router')` 即可将控制权交回给路由实例。 +### Skipping out of a router + +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. -该示例展示了一个中间件子栈,用于处理 `/user/:id` 路径的 GET 请求。 +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -503,12 +524,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## 错误处理中间件 - - -错误处理中间件始终接收**四个**参数。 你必须传入**四个参数**,才能将其标识为错误处理中间件函数。 即使你不需要使用 `next` 对象,也必须声明它,以保持函数签名不变。 否则,`next` 对象会被解析为常规中间件,从而无法处理错误。 - - - 定义错误处理中间件函数的方式与其他中间件一致,唯一区别是它接收四个参数而非三个,标准函数签名为:`(err, req, res, next)`。 ```js @@ -527,7 +542,17 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For details about error-handling middleware, see: [Error handling](/guide/error-handling). + + +错误处理中间件始终接收**四个**参数。 你必须传入**四个参数**,才能将其标识为错误处理中间件函数。 即使你不需要使用 `next` 对象,也必须声明它,以保持函数签名不变。 否则,`next` 对象会被解析为常规中间件,从而无法处理错误。 + + + + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## 内置中间件 @@ -537,6 +562,8 @@ Express 包含以下内置中间件函数: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. - [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **注意:此功能仅在 Express 4.16.0 及以上版本可用** +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. **NOTE: Available with Express 4.17.0+** +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. **NOTE: Available with Express 4.17.0+** - [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **注意:此功能仅在 Express 4.16.0 及以上版本可用** ## 第三方中间件 @@ -578,4 +605,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -如需查看可配合 Express 使用的常用第三方中间件部分清单,请参阅:[第三方中间件](/resources/middleware)。 + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/zh-cn/4x/guide/using-template-engines.mdx b/src/content/docs/zh-cn/4x/guide/using-template-engines.mdx index 2c0b5e9cce..a736d0a865 100644 --- a/src/content/docs/zh-cn/4x/guide/using-template-engines.mdx +++ b/src/content/docs/zh-cn/4x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: 在 Express 中使用模板引擎 -description: 了解如何在 Express.js 中集成并使用 Pug、Handlebars、EJS 等模板引擎,高效渲染动态 HTML 页面。 +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -9,15 +9,15 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa 模板引擎能够让你在应用中使用静态模板文件。 运行时,模板引擎会将模板文件中的变量替换为实际值,并把模板转换成HTML文件发送至客户端。 这种方式能够简化HTML页面的开发。 -[Express应用生成器](/en/starter/generator)默认使用[Pug](https://pugjs.org/api/getting-started.html),同时也支持[Handlebars](https://www.npmjs.com/package/handlebars)、[EJS](https://www.npmjs.com/package/ejs)等模板引擎。 +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`,模板文件所在的目录。 例如:`app.set('views', './views')`。 该配置默认为应用根目录下的`views`目录。 - `view engine`,要使用的模板引擎。 例如,要使用 Pug 模板引擎:`app.set('view engine', 'pug')`。 -然后安装对应的模板引擎 npm 包;例如要安装 Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -25,6 +25,7 @@ To render template files, set the following [application setting properties](/ap 符合 Express 规范的模板引擎如 Pug会导出一个名为`__express(filePath, options, callback)`的函数,`res.render()`会调用该函数来渲染模板代码。 有些模板引擎并不遵循此规范。 [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate)库遵循此规范,对所有主流Node.js模板引擎进行了统一封装,因此可在Express中无缝使用。 +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/zh-cn/4x/guide/writing-middleware.mdx b/src/content/docs/zh-cn/4x/guide/writing-middleware.mdx index 4446511869..0fbb60b3f2 100644 --- a/src/content/docs/zh-cn/4x/guide/writing-middleware.mdx +++ b/src/content/docs/zh-cn/4x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: 学习如何为 Express.js 应用编写自定义中间件函数, --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the `next` function in the application's request-response cycle. `next` 函数是 Express 路由器中的一个函数,调用该函数时,会执行当前中间件之后的下一个中间件。 @@ -193,7 +194,8 @@ app.listen(3000); ### 中间件函数 requestTime -接下来,我们将创建一个名为 `requestTime` 的中间件函数,并向请求对象添加一个名为 `requestTime` 的属性。 +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -409,9 +411,13 @@ app.listen(3000); -由于你可以访问请求对象、响应对象、堆栈中的下一个中间件函数以及整个 Node.js API,因此中间件函数的用途是无限的。 +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -For more information about Express middleware, see: [Using Express middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## 可配置中间件 diff --git a/src/content/docs/zh-cn/4x/starter/basic-routing.mdx b/src/content/docs/zh-cn/4x/starter/basic-routing.mdx index 3048efa140..ed97db3348 100644 --- a/src/content/docs/zh-cn/4x/starter/basic-routing.mdx +++ b/src/content/docs/zh-cn/4x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: 学习 Express.js 应用程序中路由的基础知识,包括如 --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; 路由用于定义应用程序如何响应客户端对指定端点的请求;端点由统一资源标识符(URI,或称路径)和具体的 HTTP 请求方法(GET、POST 等)组成。 @@ -95,4 +96,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -For more details about routing, see the [routing guide](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/zh-cn/4x/starter/faq.mdx b/src/content/docs/zh-cn/4x/starter/faq.mdx index 7305ba9c14..cac9efb412 100644 --- a/src/content/docs/zh-cn/4x/starter/faq.mdx +++ b/src/content/docs/zh-cn/4x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ  常见问题解答 description: 查找有关 Express.js 的常见问题解答,涵盖应用程序架构、数据模型、身份验证、模板引擎、错误处理等相关主题。 --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## 我应该如何组织我的应用程序? 这个问题没有标准答案。 答案取决于你的应用规模以及参与开发的团队。 为实现最大限度的灵活性,Express 不会对项目结构做任何强制限定。 @@ -33,7 +35,11 @@ See [LoopBack](http://loopback.io) for an Express-based framework that is center Express 支持所有符合 `(path, locals, callback)` 入参规范的模板引擎。 如需统一各类模板引擎的接口与缓存机制,可查看 [consolidate.js](https://github.com/visionmedia/consolidate.js) 项目以获取相关支持。 未列入清单的模板引擎也可能兼容 Express 的调用规范。 -For more information, see [Using template engines with Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## 如何处理 404 响应? @@ -75,7 +81,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For more information, see [Error handling](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## 如何渲染纯 HTML? diff --git a/src/content/docs/zh-cn/4x/starter/installing.mdx b/src/content/docs/zh-cn/4x/starter/installing.mdx index 9e1a6cb7d1..1b64b9fc5f 100644 --- a/src/content/docs/zh-cn/4x/starter/installing.mdx +++ b/src/content/docs/zh-cn/4x/starter/installing.mdx @@ -76,7 +76,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/zh-cn/4x/starter/static-files.mdx b/src/content/docs/zh-cn/4x/starter/static-files.mdx index 81262e4ac3..27cb5a3424 100644 --- a/src/content/docs/zh-cn/4x/starter/static-files.mdx +++ b/src/content/docs/zh-cn/4x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: 了解如何在 Express.js 应用中使用内置的 `static` 中间 --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; 要托管图片、CSS 文件和 JavaScript 文件等静态文件,需使用 Express 内置的 `express.static` 中间件函数。 @@ -84,4 +85,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + For more details about the `serve-static` function and its options, see [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/zh-cn/5x/guide/debugging.mdx b/src/content/docs/zh-cn/5x/guide/debugging.mdx index beb9dc3f3b..f0d20ba0ff 100644 --- a/src/content/docs/zh-cn/5x/guide/debugging.mdx +++ b/src/content/docs/zh-cn/5x/guide/debugging.mdx @@ -4,103 +4,218 @@ description: 通过设置 DEBUG 环境变量来开启并使用 Express.js 应用 --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -若要查看 Express 中使用的所有内部日志,请在启动应用时将 `DEBUG` 环境变量设置为 `express:*`。 +To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*,router,router:*` when launching your app. Routing is handled by the separate [router](https://github.com/pillarjs/router) package, so its logs live under the `router` namespace and are not included in `express:*`. ```bash -$ DEBUG=express:* node index.js +$ DEBUG=express:*,router,router:* node index.js ``` 在 Windows 系统上,请使用对应的命令。 ```bash -> $env:DEBUG = "express:*"; node index.js +> $env:DEBUG = "express:*,router,router:*"; node index.js ``` -Running this command on the default app generated by the [express generator](/starter/generator) prints the following output: +Running this command on a small app with a JSON body parser and a mounted router prints the following output: + +```cjs title="index.cjs" +const express = require('express'); + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` + +```mjs title="index.mjs" +import express from 'express'; + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` ```bash -$ DEBUG=express:* node ./bin/www - express:router:route new / +0ms - express:router:layer new / +1ms - express:router:route get / +1ms - express:router:layer new / +0ms - express:router:route new / +1ms - express:router:layer new / +0ms - express:router:route get / +0ms - express:router:layer new / +0ms - express:application compile etag weak +1ms - express:application compile query parser extended +0ms - express:application compile trust proxy false +0ms - express:application booting in development mode +1ms - express:router use / query +0ms - express:router:layer new / +0ms - express:router use / expressInit +0ms - express:router:layer new / +0ms - express:router use / favicon +1ms - express:router:layer new / +0ms - express:router use / logger +0ms - express:router:layer new / +0ms - express:router use / jsonParser +0ms - express:router:layer new / +1ms - express:router use / urlencodedParser +0ms - express:router:layer new / +0ms - express:router use / cookieParser +0ms - express:router:layer new / +0ms - express:router use / stylus +90ms - express:router:layer new / +0ms - express:router use / serveStatic +0ms - express:router:layer new / +0ms - express:router use / router +0ms - express:router:layer new / +1ms - express:router use /users router +0ms - express:router:layer new /users +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms +$ DEBUG=express:*,router,router:* node index.js + express:application set "x-powered-by" to true +0ms + express:application set "etag" to 'weak' +3ms + express:application set "etag fn" to [Function: generateETag] +0ms + express:application set "env" to 'development' +1ms + express:application set "query parser" to 'simple' +0ms + express:application set "query parser fn" to [Function: parse] +0ms + express:application set "subdomain offset" to 2 +1ms + express:application set "trust proxy" to false +0ms + express:application set "trust proxy fn" to [Function: trustNone] +1ms + express:application booting in development mode +0ms + express:application set "view" to [Function: View] +0ms + express:application set "views" to '/projects/example/views' +1ms + express:application set "jsonp callback name" to 'callback' +0ms + router use '/' jsonParser +0ms + router:layer new '/' +0ms + router:route new '/' +0ms + router:layer new '/' +3ms + router:route get / +0ms + router:layer new '/' +1ms + router use '/users' router +4ms + router:layer new '/users' +0ms + router:route new '/' +1ms + router:layer new '/' +0ms + router:route get / +1ms + router:layer new '/' +1ms ``` 随后向该应用发送请求时,你会看到 Express 代码中指定的日志: ```bash - express:router dispatching GET / +4h - express:router query : / +2ms - express:router expressInit : / +0ms - express:router favicon : / +0ms - express:router logger : / +1ms - express:router jsonParser : / +0ms - express:router urlencodedParser : / +1ms - express:router cookieParser : / +0ms - express:router stylus : / +0ms - express:router serveStatic : / +2ms - express:router router : / +2ms - express:router dispatching GET / +1ms - express:view lookup "index.pug" +338ms - express:view stat "/projects/example/views/index.pug" +0ms - express:view render "/projects/example/views/index.pug" +1ms + router dispatching GET /users +712ms + router jsonParser : /users +1ms + router trim prefix (/users) from url /users +2ms + router router /users : /users +0ms + router dispatching GET / +0ms +``` + +To see the logs only from the router implementation, set the value of `DEBUG` to `router,router:*`. 同理,若仅查看来自应用实现的日志,请将 `DEBUG` 的值设置为 `express:application`,以此类推。 + +## Using `debug` in your own code + +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: + + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); ``` -若仅查看来自路由实现的日志,请将 `DEBUG` 的值设置为 `express:router`。 同理,若仅查看来自应用实现的日志,请将 `DEBUG` 的值设置为 `express:application`,以此类推。 +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; -## 由 `express` 生成的应用 +const debug = debugModule('myapp:server'); +const app = express(); -由 `express` 命令生成的应用会使用 `debug` 模块,且其调试命名空间的作用域限定为应用名称。 +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); -例如,如果你使用 `$ express sample-app` 命令生成了应用,可以通过以下命令启用调试语句: +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` 你可以通过指定以英文逗号分隔的名称列表,来启用多个调试命名空间: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,router node index.js ``` +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*,router,router:*" } +} +``` + +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## 高级选项 在通过 Node.js 运行时,你可以设置若干环境变量来更改调试日志的行为: diff --git a/src/content/docs/zh-cn/5x/guide/error-handling.mdx b/src/content/docs/zh-cn/5x/guide/error-handling.mdx index d4795c0e3e..6919661535 100644 --- a/src/content/docs/zh-cn/5x/guide/error-handling.mdx +++ b/src/content/docs/zh-cn/5x/guide/error-handling.mdx @@ -11,6 +11,8 @@ import Alert from '@components/primitives/Alert/Alert.astro'; 确保 Express 能够捕获路由处理器和中间件运行时发生的所有错误,这一点至关重要。 +### Errors in synchronous code + 路由处理函数与中间件内同步代码产生的错误无需额外处理。 倘若同步代码抛出错误,Express 会捕获并处理该错误。 举个例子: ```js @@ -27,48 +29,24 @@ app.get('/', (req: Request, res: Response) => { }); ``` -对于路由处理函数和中间件调用的异步函数所返回的错误,你必须将它们传递给 `next()` 函数,Express 会在该函数中捕获并处理这些错误。 举个例子: - -```js -app.get('/', (req, res, next) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` - -```ts -import { type Request, type Response, type NextFunction } from 'express'; - -app.get('/', (req: Request, res: Response, next: NextFunction) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` +### Errors in asynchronous code -从 Express 5 开始,返回 Promise 的路由处理程序和中间件在拒绝(reject)或抛出错误时,将自动调用 `next(value)`。 -举个例子: +The recommended way to write asynchronous handlers is with `async` functions. +Route handlers and middleware that return a Promise call `next(value)` +automatically when they reject or throw an error, and `async` functions always +return a Promise, so their errors reach Express with no extra work. 举个例子: ```js -app.get('/user/:id', async (req, res, next) => { +app.get('/user/:id', async (req, res) => { const user = await getUserById(req.params.id); res.send(user); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', async (req: Request, res: Response) => { const user = await getUserById(req.params.id); res.send(user); }); @@ -78,45 +56,41 @@ app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => 如果向 `next()` 传入任意参数(字符串 `'route'` 除外),Express 会将当前请求视作出错,并跳过后续所有非错误处理的路由与中间件函数。 -如果序列中的回调函数不返回数据、仅返回错误,你可以将代码简化如下: +### Working with promise chains + +If you build a promise chain instead of using an `async` function, return the +promise from the handler and Express will likewise call `next` automatically +when it rejects: ```js -app.get('/', [ - function (req, res, next) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req, res) { - res.send('OK'); - }, -]); +app.get('/', (req, res) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/', [ - function (req: Request, res: Response, next: NextFunction) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req: Request, res: Response) { - res.send('OK'); - }, -]); +app.get('/', (req: Request, res: Response) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` -在上述示例中,`next` 被作为 `fs.writeFile` 的回调函数传入,无论是否存在错误都会被调用。 若无错误,则执行第二个处理函数;否则 Express 会捕获并处理该错误。 - -你必须捕获在路由处理程序或中间件中调用的异步代码里发生的错误,并将它们传递给 Express 进行处理。 举个例子: +If the promise is not returned, Express does not know it exists, and you must +route the error yourself by providing `next` as the final catch handler. +Without it, the rejection would be unhandled and crash the process: ```js app.get('/', (req, res, next) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` @@ -124,27 +98,32 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` -上述示例使用 `try...catch` 代码块捕获异步代码中的错误,并将其传递给 Express。 如果省略 `try...catch` 代码块,Express 将无法捕获该错误,因为它不属于同步处理程序代码的一部分。 +This works because if a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, `.catch` calls its handler with the error as the first argument, which is exactly the argument `next` expects, so the error reaches Express. -使用 Promise 来避免 `try...catch` 代码块的开销,或在使用返回 Promise 的函数时采用此方式。 举个例子: +### Working with callback APIs + +Errors produced by callback-based APIs, such as those in `node:fs`, are not +thrown and are not part of any promise. The callback receives them as its first +argument, and you must pass them to the `next()` function yourself, where +Express will catch and process them. 举个例子: ```js app.get('/', (req, res, next) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` @@ -152,15 +131,43 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` -由于 Promise 会自动捕获同步错误和被拒绝的 Promise,你只需将 `next` 作为最终的 catch 处理程序传入即可,Express 会捕获错误,因为 catch 处理程序会将错误作为第一个参数传入。 +如果序列中的回调函数不返回数据、仅返回错误,你可以将代码简化如下: + +```js +app.get('/', [ + function (req, res, next) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req, res) { + res.send('OK'); + }, +]); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', [ + function (req: Request, res: Response, next: NextFunction) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req: Request, res: Response) { + res.send('OK'); + }, +]); +``` + +在上述示例中,`next` 被作为 `fs.writeFile` 的回调函数传入,无论是否存在错误都会被调用。 若无错误,则执行第二个处理函数;否则 Express 会捕获并处理该错误。 你也可以使用处理程序链,将异步代码简化为简单逻辑,从而依靠同步错误捕获机制。 举个例子: @@ -196,7 +203,40 @@ app.get('/', [ ]); ``` -上述示例包含几条来自 `readFile` 调用的简单语句。 如果 `readFile` 引发错误,则会将错误传递给 Express;否则你将迅速回到处理程序链中下一个处理函数的同步错误处理流程。 然后,上述示例会尝试处理数据。 如果此过程失败,同步错误处理程序将会捕获该错误。 如果你将此处理逻辑写在 `readFile` 回调函数内部,应用程序可能会直接退出,Express 错误处理程序将无法执行。 +The above example contains a couple of trivial statements following the `readFile` +call. 如果 `readFile` 引发错误,则会将错误传递给 Express;否则你将迅速回到处理程序链中下一个处理函数的同步错误处理流程。 然后,上述示例会尝试处理数据。 如果此过程失败,同步错误处理程序将会捕获该错误。 如果你将此处理逻辑写在 `readFile` 回调函数内部,应用程序可能会直接退出,Express 错误处理程序将无法执行。 + +Finally, for asynchronous code that provides no error-first callback, such as a +timer, catch errors inside the asynchronous code itself and pass them to +Express: + +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', (req: Request, res: Response, next: NextFunction) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +上述示例使用 `try...catch` 代码块捕获异步代码中的错误,并将其传递给 Express。 如果省略 `try...catch` 代码块,Express 将无法捕获该错误,因为它不属于同步处理程序代码的一部分。 无论你使用哪种方法,若希望 Express 错误处理程序被调用且应用程序持续运行,必须确保 Express 能够接收到错误。 @@ -378,7 +418,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Also in this example, `clientErrorHandler` is defined as follows; in this case, the error is explicitly passed along to the next one. -Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/zh-cn/5x/guide/overriding-express-api.mdx b/src/content/docs/zh-cn/5x/guide/overriding-express-api.mdx index 6573560b24..6e87e07a63 100644 --- a/src/content/docs/zh-cn/5x/guide/overriding-express-api.mdx +++ b/src/content/docs/zh-cn/5x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -Express API 由请求对象和响应对象上的多种方法与属性组成。 这些内容通过原型继承。 Express API 有两个扩展点: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. 这些内容通过原型继承。 Express API 有两个扩展点: 1. `express.request` 和 `express.response` 上的全局原型。 2. 应用专属原型位于 `app.request` 和 `app.response`。 diff --git a/src/content/docs/zh-cn/5x/guide/routing.mdx b/src/content/docs/zh-cn/5x/guide/routing.mdx index 4e27176f19..b777552a73 100644 --- a/src/content/docs/zh-cn/5x/guide/routing.mdx +++ b/src/content/docs/zh-cn/5x/guide/routing.mdx @@ -7,14 +7,16 @@ import Alert from '@components/primitives/Alert/Alert.astro'; **路由**是指应用程序的端点(URI)如何响应客户端的请求。 For an introduction to routing, see [Basic routing](/starter/basic-routing). +For an introduction to routing, see [Basic routing](/starter/basic-routing). 你可以使用 Express `app` 对象中与 HTTP 方法对应的方法来定义路由; 例如,`app.get()` 处理 GET 请求,`app.post` 处理 POST 请求。 For a full list, see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. 换句话说,应用程序会“监听”匹配指定路由和方法的请求,当检测到匹配时,就会调用指定的回调函数。 +换句话说,应用程序会“监听”匹配指定路由和方法的请求,当检测到匹配时,就会调用指定的回调函数。 These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. +事实上,路由方法可以接受多个回调函数作为参数。 事实上,路由方法可以接受多个回调函数作为参数。 对于多个回调函数,务必在回调函数中传入`next`作为参数,然后在函数体内调用`next()`,将控制权传递给下一个回调函数。 @@ -84,10 +86,13 @@ app.post('/', (req: Request, res: Response) => { }); ``` -Express 支持对应于所有 HTTP 请求方法的方法:get、post 等。 -For a full list, see [app.METHOD](/api/application#appmethod). +你可以使用 Express `app` 对象中与 HTTP 方法对应的方法来定义路由; +例如,`app.get()` 处理 GET 请求,`app.post` 处理 POST 请求。 For a full list, +see [app.METHOD](/api/application#appmethod). +You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to +specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -有一种特殊的路由方法 **app.all()**,用于为某一路径加载所有 HTTP 请求方法通用的中间件函数。 For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +有一种特殊的路由方法 **app.all()**,用于为某一路径加载所有 HTTP 请求方法通用的中间件函数。 For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -107,18 +112,19 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Route paths -路由路径与请求方法结合,定义了可以接收请求的端点。 路由路径可以是字符串或正则表达式。 +路由路径与请求方法结合,定义了可以接收请求的端点。 路由路径可以是字符串或正则表达式。 路由路径与请求方法结合,定义了可以接收请求的端点。 路由路径可以是字符串或正则表达式。 They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. Express 使用 [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) v8 匹配路由路径;有关定义路由路径的所有可用方式,请参阅 path-to-regexp 文档。 [Express Playground Router](https://bjohansebas.github.io/playground-router/) 是一款便捷的 Express 基础路由在线测试工具,但该工具不支持路由规则匹配。 +[Express Playground Router](https://bjohansebas.github.io/playground-router/) 是一款便捷的 Express 基础路由在线测试工具,但该工具不支持路由规则匹配。 ### String paths -字符串路径会精确匹配请求。 点(`.`)和连字符(`-`)会按字面含义解析。 +字符串路径会精确匹配请求。 点(`.`)和连字符(`-`)会按字面含义解析。 点(`.`)和连字符(`-`)会按字面含义解析。 查询字符串不属于路由路径的一部分 @@ -152,77 +158,9 @@ app.get('/random.text', (req: Request, res: Response) => { }); ``` -### Wildcards - -通配符可以匹配前缀后的任意路径。 它们必须像路由参数一样拥有名称,并且会被捕获为**路径片段组成的数组**。 - -```js -app.get('/files/*filepath', (req, res) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -若要同时匹配根路径,请将通配符用花括号包裹: - -```js -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req, res) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req: Request, res: Response) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -### Optional segments - -使用花括号在路由路径中定义可选片段。 当该片段不存在时,该参数会从 `req.params` 中省略。 - -```js -app.get('/:file{.:ext}', (req, res) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/:file{.:ext}', (req: Request, res: Response) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -字符 `?`、`+`、`*`、`[]` 和 `()` 为保留字符,不能在路由路径中用作字面字符。 如有需要,可使用`\`对其进行转义。 +The characters `?`, `+`, `*`, `[]`, `()`, and `!` are reserved and cannot be used as literal characters in route paths, and braces are reserved for [optional segments](#optional-segments). 如有需要,可使用`\`对其进行转义。 @@ -258,7 +196,11 @@ app.get(/.*fly$/, (req: Request, res: Response) => { ## Route parameters -路由参数是命名式URL片段,用于捕获URL中对应位置所指定的值。 捕获的值会存入`req.params`对象,路径中定义的路由参数名作为该对象对应的键名。 +路由参数是命名式URL片段,用于捕获URL中对应位置所指定的值。 捕获的值会存入`req.params`对象,路径中定义的路由参数名作为该对象对应的键名。 They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces. 捕获的值会存入`req.params`对象,路径中定义的路由参数名作为该对象对应的键名。 They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces. + +### Named parameters + +Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below. ``` Route path: /users/:userId/books/:bookId @@ -292,7 +234,7 @@ app.get('/users/:userId/books/:bookId', sendParams); -路由参数的名称必须由“单词字符”([A-Za-z0-9_])组成。 +The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example `:"user-name"`. @@ -312,14 +254,122 @@ req.params: { "genus": "Prunus", "species": "persica" } -路由路径中不支持正则表达式字符。 请改用路径数组或正则表达式。 +Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as `:userId(\d+)`. Use an array of paths or a full regular expression instead. See the [path route matching syntax](/guide/migrating-5#path-syntax) for more information. +### Wildcards + +通配符可以匹配前缀后的任意路径。 通配符可以匹配前缀后的任意路径。 Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string. + +```js +app.get('/files/*filepath', (req, res) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +若要同时匹配根路径,请将通配符用花括号包裹: + +```js +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req, res) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req: Request, res: Response) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +### Optional segments + +使用花括号在路由路径中定义可选片段。 使用花括号在路由路径中定义可选片段。 当该片段不存在时,该参数会从 `req.params` 中省略。 + +```js +app.get('/:file{.:ext}', (req, res) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/:file{.:ext}', (req: Request, res: Response) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters: + +```js +app.get('/user/\{:id}', (req, res) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req, res) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/user/\{:id}', (req: Request, res: Response) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req: Request, res: Response) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +不要将路由路径中斜杠的位置与[`strict routing` 设置](/api/application/#application-settings)混淆,后者针对的是请求 URL:它控制以路由路径未要求的斜杠结尾的 URL 是否仍然匹配。 例如,对 `/order/` 的请求默认匹配 `/order{/:id}` 路由,但在启用 strict routing 时会返回 404 错误;`/user/` 的末尾斜杠不受影响,因为 `/user/\{:id}` 路由要求它。 上面示例中注释的所有请求无论该设置如何,行为都相同。## Route handlersYou can provide multiple callback functions that + ## Route handlers -You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. 唯一的例外是这些回调函数可以调用 `next('route')` 来跳过剩余的路由回调。 你可以通过这种机制为路由施加前置条件,如果没有理由继续执行当前路由,则将控制权传递给后续路由。 +You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. 唯一的例外是这些回调函数可以调用 `next('route')` 来跳过剩余的路由回调。 你可以通过这种机制为路由施加前置条件,如果没有理由继续执行当前路由,则将控制权传递给后续路由。 你可以通过这种机制为路由施加前置条件,如果没有理由继续执行当前路由,则将控制权传递给后续路由。```js +app.get('/user/:id', (req, res, next) => { +if (req.params.i + +```` ```js app.get('/user/:id', (req, res, next) => { @@ -332,7 +382,7 @@ app.get('/user/:id', (req, res, next) => { app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0'); }); -``` +```` ```ts import { type Request, type Response, type NextFunction } from 'express'; @@ -354,15 +404,17 @@ app.get('/user/:id', (req: Request, res: Response) => { - `GET /user/5` → 由第一个路由处理 → 返回 "User 5" - `GET /user/0` → 第一个路由调用 `next('route')`,跳转到下一个匹配的 `/user/:id` 路由 -路由处理程序可以采用函数、函数数组或二者结合的形式,如下示例所示。 +路由处理程序可以采用函数、函数数组或二者结合的形式,如下示例所示。A single callback function can handle a route. For example:```js + +```` -单个回调函数即可处理一个路由。 举个例子: +单个回调函数即可处理一个路由。 ```js app.get('/example/a', (req, res) => { res.send('Hello from A!'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -372,7 +424,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -多个回调函数可以处理同一个路由(请确保你指定了 `next` 对象)。 举个例子: +多个回调函数可以处理同一个路由(请确保你指定了 `next` 对象)。 举个例子: 举个例子: ```js app.get( @@ -402,7 +454,7 @@ app.get( ); ``` -一个回调函数数组可以处理一个路由。 举个例子: +一个回调函数数组可以处理一个路由。 ```js const cb0 = function (req, res, next) { @@ -496,26 +548,33 @@ app.get( ## Response methods -下表中的响应对象(`res`)方法可向客户端发送响应,并终止请求-响应循环。 如果路由处理程序未调用这些方法中的任何一个,客户端请求将一直处于挂起状态。 +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. 如果路由处理程序未调用这些方法中的任何一个,客户端请求将一直处于挂起状态。| Method | Description -| Method | 描述 | -| ----------------------------------------------- | ---------------------------------------------------- | -| [res.download()](/api/response#resdownload) | 提示客户端下载一个文件。 | -| [res.end()](/api/response#resend) | 结束响应流程。 | -| [res.json()](/api/response#resjson) | 发送 JSON 响应。 | -| [res.jsonp()](/api/response#resjsonp) | 发送支持 JSONP 的 JSON 响应。 | -| [res.redirect()](/api/response#resredirect) | 重定向请求。 | -| [res.render()](/api/response#resrender) | 渲染视图模板。 | -| [res.send()](/api/response#ressend) | 发送多种类型的响应。 | -| [res.sendFile()](/api/response#ressendfile) | 以八位字节流的形式发送文件。 | -| [res.sendStatus()](/api/response#ressendstatus) | 设置响应状态码,并将其字符串表示形式作为响应体发送。 | +| | | +| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/api/response#resdownload) | 提示客户端下载一个文件。 | +| [res.end()](/api/response#resend) | 结束响应流程。 | +| [res.json()](/api/response#resjson) | 发送 JSON 响应。 | +| [res.jsonp()](/api/response#resjsonp) | 发送支持 JSONP 的 JSON 响应。 | +| | 重定向请求。 | +| [res.render()](/api/response#resrender) | 渲染视图模板。 | +| [res.send()](/api/response#ressend) | 发送多种类型的响应。 | +| [res.sendFile()](/api/response#ressendfile) | 以八位字节流的形式发送文件。 | +| [res.sendStatus()](/api/response#ressendstatus) | 设置响应状态码,并将其字符串表示形式作为响应体发送。 \|## app.route()You can create chainable route handlers for a rou | ## app.route() 你可以使用 `app.route()` 为路由路径创建可链式调用的路由处理程序。 -由于路径在单个位置指定,因此创建模块化路由十分有用,同时还能减少冗余和拼写错误。 For more information about routes, see: [Router() documentation](/api/router). +你可以使用 `app.route()` 为路由路径创建可链式调用的路由处理程序。 +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router).Here is an example of chained route handlers that are defined by us + +以下是使用 `app.route()` 定义的链式路由处理程序示例。```js +app +.route('/book') +.get((req, res) => { +res.send('Ge -以下是使用 `app.route()` 定义的链式路由处理程序示例。 +```` ```js app @@ -529,7 +588,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -549,9 +608,9 @@ app ## express.Router -使用 `express.Router` 类创建模块化、可挂载的路由处理程序。 `Router` 实例是一个完整的中间件和路由系统;因此,它通常被称为“迷你应用”。 +使用 `express.Router` 类创建模块化、可挂载的路由处理程序。 使用 `express.Router` 类创建模块化、可挂载的路由处理程序。 `Router` 实例是一个完整的中间件和路由系统;因此,它通常被称为“迷你应用”。The following example creates a router as a module, loads a middlewThe following example creates a router as a module, loads a middlew -以下示例创建一个路由模块,在其中加载中间件函数、定义若干路由,并将该路由模块挂载到主应用的指定路径上。 +以下示例创建一个路由模块,在其中加载中间件函数、定义若干路由,并将该路由模块挂载到主应用的指定路径上。Create a router file named `birds.js` in the app directory, with thCreate a router file named `birds.js` in the app directory, with th 在应用目录中创建一个名为 `birds.js` 的路由文件,内容如下: @@ -644,10 +703,13 @@ import birds from './birds'; app.use('/birds', birds); ``` -应用现在将能够处理指向 `/birds` 和 `/birds/about` 的请求,同时会调用该路由专用的 `timeLog` 中间件函数。 +应用现在将能够处理指向 `/birds` 和 `/birds/about` 的请求,同时会调用该路由专用的 `timeLog` 中间件函数。But if the parent route `/birds` has path parameters, it will not b -但如果父路由 `/birds` 包含路径参数,默认情况下子路由无法访问这些参数。 To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +但如果父路由 `/birds` 包含路径参数,默认情况下子路由无法访问这些参数。 但如果父路由 `/birds` 包含路径参数,默认情况下子路由无法访问这些参数。 To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter).```js +const router = express.Router({ mergeParams: true }); + +```` ```js const router = express.Router({ mergeParams: true }); -``` +```` diff --git a/src/content/docs/zh-cn/5x/guide/using-middleware.mdx b/src/content/docs/zh-cn/5x/guide/using-middleware.mdx index f53c176c60..919848a0c6 100644 --- a/src/content/docs/zh-cn/5x/guide/using-middleware.mdx +++ b/src/content/docs/zh-cn/5x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: 了解如何在 Express.js 应用中使用中间件,包括应用 import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express 是一款路由与中间件 Web 框架,自身仅提供极简的基础功能:一个 Express 应用本质上就是一连串中间件函数的调用。 +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -_Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the next middleware function in the application's request-response cycle. 下一个中间件函数通常使用名为`next`的变量来表示。 +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` 中间件函数可执行下列任务: - 执行任意代码。 -- 修改请求对象与响应对象。 +- Modify the request and response objects. - 终止请求-响应周期。 -- 调用栈中的下一个中间件函数。 +- Pass control to the next middleware function. -如果当前中间件函数没有终止请求-响应周期,它必须调用 `next()` 以将控制权传递给下一个中间件函数。 否则,请求将会被挂起。 +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. 否则,请求将会被挂起。 Express 应用可以使用以下类型的中间件: @@ -27,14 +32,15 @@ Express 应用可以使用以下类型的中间件: - [Built-in middleware](#middleware.built-in) - [Third-party middleware](#middleware.third-party) -你可以通过可选的挂载路径加载应用级中间件和路由级中间件。 -你也可以同时加载一系列中间件函数,这会在挂载点处创建中间件系统的一个子栈。 +你可以通过可选的挂载路径加载应用级中间件和路由级中间件。 Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## 应用级中间件 -Bind application-level middleware to an instance of the [app object](/api#app) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -本示例展示了一个没有挂载路径的中间件函数。 每当应用接收请求时,该函数都会被执行。 +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,7 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -本示例展示了一个挂载在 `/user/:id` 路径上的中间件函数。 只要是发往 `/user/:id` 路径的任意类型 HTTP 请求,都会执行该中间件函数。 +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -86,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` +### Route handlers + 该示例展示了一条路由及其处理函数(中间件体系)。 该函数处理指向 `/user/:id` 路径的 GET 请求。 ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -下面是在指定挂载路径的挂载点加载一系列中间件函数的示例。 -该示例演示了一个中间件子栈,会对所有访问 `/user/:id` 路径的各类 HTTP 请求打印请求信息。 +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -135,9 +146,9 @@ app.use( ); ``` -路由处理程序支持为同一个路径定义多条路由。 下面的示例为 `/user/:id` 路径的 GET 请求定义了两条路由。 第二条路由不会报错,但永远不会被执行,因为第一条路由已经结束了请求-响应周期。 +### Multiple route handlers -该示例展示了一个中间件子栈,用于处理 `/user/:id` 路径的 GET 请求。 +路由处理程序支持为同一个路径定义多条路由。 下面的示例为 `/user/:id` 路径的 GET 请求定义了两条路由。 第二条路由不会报错,但永远不会被执行,因为第一条路由已经结束了请求-响应周期。 ```js app.get( @@ -146,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -166,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -若要跳过路由中间件栈中剩余的中间件函数,调用 `next('route')` 即可将控制权传递给下一条路由。 +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -185,7 +198,7 @@ app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { -该示例展示了一个中间件子栈,用于处理 `/user/:id` 路径的 GET 请求。 +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -196,14 +209,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -219,21 +232,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -中间件也可以定义在数组中,实现复用。 +### Reusable middleware arrays -该示例展示了一个使用数组封装的中间件子栈,用于处理 `/user/:id` 路径的 GET 请求。 +Middleware functions can also be grouped into arrays for better reusability. 该示例展示了一个使用数组封装的中间件子栈,用于处理 `/user/:id` 路径的 GET 请求。 ```js function logOriginalUrl(req, res, next) { @@ -247,7 +260,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -266,14 +279,14 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## 路由级中间件 -路由级中间件的工作方式与应用级中间件完全相同,唯一区别是它绑定到 `express.Router()` 的实例上。 +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); @@ -317,19 +330,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -367,19 +380,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -417,19 +430,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -438,9 +451,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -若要跳过当前路由实例中剩余的中间件函数,调用 `next('router')` 即可将控制权交回给路由实例。 +### Skipping out of a router + +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. -该示例展示了一个中间件子栈,用于处理 `/user/:id` 路径的 GET 请求。 +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -509,12 +524,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## 错误处理中间件 - - -错误处理中间件始终接收**四个**参数。 你必须传入**四个参数**,才能将其标识为错误处理中间件函数。 即使你不需要使用 `next` 对象,也必须声明它,以保持函数签名不变。 否则,`next` 对象会被解析为常规中间件,从而无法处理错误。 - - - 定义错误处理中间件函数的方式与其他中间件一致,唯一区别是它接收四个参数而非三个,标准函数签名为:`(err, req, res, next)`。 ```js @@ -533,17 +542,27 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For details about error-handling middleware, see: [Error handling](/guide/error-handling). + + +错误处理中间件始终接收**四个**参数。 你必须传入**四个参数**,才能将其标识为错误处理中间件函数。 即使你不需要使用 `next` 对象,也必须声明它,以保持函数签名不变。 否则,`next` 对象会被解析为常规中间件,从而无法处理错误。 -## 内置中间件 + + + -从 4.x 版本开始,Express 不再依赖 [Connect](https://github.com/senchalabs/connect)。 之前包含在 Express 中的中间件函数,现在已经拆分到独立的模块中;查看[中间件函数列表](https://github.com/senchalabs/connect#middleware)。 +For more information, see the [Error handling](/guide/error-handling) guide. + + + +## 内置中间件 Express 包含以下内置中间件函数: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. -- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **注意:此功能仅在 Express 4.16.0 及以上版本可用** -- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **注意:此功能仅在 Express 4.16.0 及以上版本可用** +- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. +- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. ## 第三方中间件 @@ -584,4 +603,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -如需查看可配合 Express 使用的常用第三方中间件部分清单,请参阅:[第三方中间件](/resources/middleware)。 + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/zh-cn/5x/guide/using-template-engines.mdx b/src/content/docs/zh-cn/5x/guide/using-template-engines.mdx index 2c0b5e9cce..a736d0a865 100644 --- a/src/content/docs/zh-cn/5x/guide/using-template-engines.mdx +++ b/src/content/docs/zh-cn/5x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: 在 Express 中使用模板引擎 -description: 了解如何在 Express.js 中集成并使用 Pug、Handlebars、EJS 等模板引擎,高效渲染动态 HTML 页面。 +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -9,15 +9,15 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa 模板引擎能够让你在应用中使用静态模板文件。 运行时,模板引擎会将模板文件中的变量替换为实际值,并把模板转换成HTML文件发送至客户端。 这种方式能够简化HTML页面的开发。 -[Express应用生成器](/en/starter/generator)默认使用[Pug](https://pugjs.org/api/getting-started.html),同时也支持[Handlebars](https://www.npmjs.com/package/handlebars)、[EJS](https://www.npmjs.com/package/ejs)等模板引擎。 +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`,模板文件所在的目录。 例如:`app.set('views', './views')`。 该配置默认为应用根目录下的`views`目录。 - `view engine`,要使用的模板引擎。 例如,要使用 Pug 模板引擎:`app.set('view engine', 'pug')`。 -然后安装对应的模板引擎 npm 包;例如要安装 Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -25,6 +25,7 @@ To render template files, set the following [application setting properties](/ap 符合 Express 规范的模板引擎如 Pug会导出一个名为`__express(filePath, options, callback)`的函数,`res.render()`会调用该函数来渲染模板代码。 有些模板引擎并不遵循此规范。 [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate)库遵循此规范,对所有主流Node.js模板引擎进行了统一封装,因此可在Express中无缝使用。 +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/zh-cn/5x/guide/writing-middleware.mdx b/src/content/docs/zh-cn/5x/guide/writing-middleware.mdx index 9dbf446c58..addc169454 100644 --- a/src/content/docs/zh-cn/5x/guide/writing-middleware.mdx +++ b/src/content/docs/zh-cn/5x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: 学习如何为 Express.js 应用编写自定义中间件函数, --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the `next` function in the application's request-response cycle. `next` 函数是 Express 路由器中的一个函数,调用该函数时,会执行当前中间件之后的下一个中间件。 @@ -164,7 +165,8 @@ app.listen(3000); ### 中间件函数 requestTime -接下来,我们将创建一个名为 `requestTime` 的中间件函数,并向请求对象添加一个名为 `requestTime` 的属性。 +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the [request object](/api/request). @@ -380,9 +382,13 @@ app.listen(3000); -由于你可以访问请求对象、响应对象、堆栈中的下一个中间件函数以及整个 Node.js API,因此中间件函数的用途是无限的。 +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -For more information about Express middleware, see: [Using Express middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## 可配置中间件 diff --git a/src/content/docs/zh-cn/5x/starter/basic-routing.mdx b/src/content/docs/zh-cn/5x/starter/basic-routing.mdx index 3048efa140..ed97db3348 100644 --- a/src/content/docs/zh-cn/5x/starter/basic-routing.mdx +++ b/src/content/docs/zh-cn/5x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: 学习 Express.js 应用程序中路由的基础知识,包括如 --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; 路由用于定义应用程序如何响应客户端对指定端点的请求;端点由统一资源标识符(URI,或称路径)和具体的 HTTP 请求方法(GET、POST 等)组成。 @@ -95,4 +96,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -For more details about routing, see the [routing guide](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/zh-cn/5x/starter/faq.mdx b/src/content/docs/zh-cn/5x/starter/faq.mdx index 87140bd6e0..c0721ae586 100644 --- a/src/content/docs/zh-cn/5x/starter/faq.mdx +++ b/src/content/docs/zh-cn/5x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ  常见问题解答 description: 查找有关 Express.js 的常见问题解答,涵盖应用程序架构、数据模型、身份验证、模板引擎、错误处理等相关主题。 --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## 我应该如何组织我的应用程序? 这个问题没有标准答案。 答案取决于你的应用规模以及参与开发的团队。 为实现最大限度的灵活性,Express 不会对项目结构做任何强制限定。 @@ -33,7 +35,11 @@ See [LoopBack](http://loopback.io) for an Express-based framework that is center Express 支持所有符合 `(path, locals, callback)` 入参规范的模板引擎。 如需统一各类模板引擎的接口与缓存机制,可查看 [consolidate.js](https://github.com/visionmedia/consolidate.js) 项目以获取相关支持。 未列入清单的模板引擎也可能兼容 Express 的调用规范。 -For more information, see [Using template engines with Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## 如何处理 404 响应? @@ -75,7 +81,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For more information, see [Error handling](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## 如何渲染纯 HTML? diff --git a/src/content/docs/zh-cn/5x/starter/installing.mdx b/src/content/docs/zh-cn/5x/starter/installing.mdx index d73ef7b75a..2b55f00c80 100644 --- a/src/content/docs/zh-cn/5x/starter/installing.mdx +++ b/src/content/docs/zh-cn/5x/starter/installing.mdx @@ -70,7 +70,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/zh-cn/5x/starter/static-files.mdx b/src/content/docs/zh-cn/5x/starter/static-files.mdx index 81262e4ac3..27cb5a3424 100644 --- a/src/content/docs/zh-cn/5x/starter/static-files.mdx +++ b/src/content/docs/zh-cn/5x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: 了解如何在 Express.js 应用中使用内置的 `static` 中间 --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; 要托管图片、CSS 文件和 JavaScript 文件等静态文件,需使用 Express 内置的 `express.static` 中间件函数。 @@ -84,4 +85,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + For more details about the `serve-static` function and its options, see [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/zh-tw/4x/guide/debugging.mdx b/src/content/docs/zh-tw/4x/guide/debugging.mdx index 24bbce3510..db5740d8a2 100644 --- a/src/content/docs/zh-tw/4x/guide/debugging.mdx +++ b/src/content/docs/zh-tw/4x/guide/debugging.mdx @@ -4,6 +4,7 @@ description: Learn how to enable and use debugging logs in Express.js applicatio --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*` when launching your app. @@ -86,22 +87,119 @@ When a request is then made to the app, you will see the logs specified in the E To see the logs only from the router implementation, set the value of `DEBUG` to `express:router`. Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on. -## Applications generated by `express` +## Using `debug` in your own code -An application generated by the `express` command uses the `debug` module and its debug namespace is scoped to the name of the application. +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: -For example, if you generated the app with `$ express sample-app`, you can enable the debug statements with the following command: + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; + +const debug = debugModule('myapp:server'); +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` You can specify more than one debug namespace by assigning a comma-separated list of names: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,express:router node index.js +``` + +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*" } +} ``` +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Advanced options When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: diff --git a/src/content/docs/zh-tw/4x/guide/error-handling.mdx b/src/content/docs/zh-tw/4x/guide/error-handling.mdx index 7cafabc5f6..de6641684c 100644 --- a/src/content/docs/zh-tw/4x/guide/error-handling.mdx +++ b/src/content/docs/zh-tw/4x/guide/error-handling.mdx @@ -62,14 +62,16 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Starting with Express 5, route handlers and middleware that return a Promise -will call `next(value)` automatically when they reject or throw an error. -For example: +Errors from rejected promises are not passed to `next` automatically, and this includes `async` functions: if an `async` route handler throws or awaits a rejected promise, the rejection is unhandled, which crashes the process on current Node.js versions. You must catch the error yourself and pass it to Express: ```js app.get('/user/:id', async (req, res, next) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` @@ -77,14 +79,22 @@ app.get('/user/:id', async (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { - const user = await getUserById(req.params.id); - res.send(user); + try { + const user = await getUserById(req.params.id); + res.send(user); + } catch (err) { + next(err); + } }); ``` -If `getUserById` throws an error or rejects, `next` will be called with either -the thrown error or the rejected value. If no rejected value is provided, `next` -will be called with a default Error object provided by the Express router. + + +Consider [updating to Express 5](/guide/migrating-5), where route handlers and middleware that +return a Promise call `next(value)` automatically when they reject or throw an error, making the +`try...catch` above unnecessary. + + If you pass anything to the `next()` function (except the string `'route'`), Express regards the current request as being an error and will skip any @@ -180,9 +190,7 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -Since promises automatically catch both synchronous errors and rejected promises, -you can simply provide `next` as the final catch handler and Express will catch errors, -because the catch handler is given the error as the first argument. +If a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, passing `next` as the handler is enough: `.catch` calls it with the error as its first argument, which is exactly the argument `next` expects, so the error reaches Express. You could also use a chain of handlers to rely on synchronous error catching, by reducing the asynchronous code to something trivial. For example: @@ -219,7 +227,7 @@ app.get('/', [ ]); ``` -The above example has a couple of trivial statements from the `readFile` +The above example contains a couple of trivial statements following the `readFile` call. If `readFile` causes an error, then it passes the error to Express, otherwise you quickly return to the world of synchronous error handling in the next handler in the chain. Then, the example above tries to process the data. If this fails, then the @@ -424,7 +432,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Also in this example, `clientErrorHandler` is defined as follows; in this case, the error is explicitly passed along to the next one. -Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/zh-tw/4x/guide/overriding-express-api.mdx b/src/content/docs/zh-tw/4x/guide/overriding-express-api.mdx index 54cef9edbc..c6afcac28b 100644 --- a/src/content/docs/zh-tw/4x/guide/overriding-express-api.mdx +++ b/src/content/docs/zh-tw/4x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -The Express API consists of various methods and properties on the request and response objects. These are inherited by prototype. There are two extension points for the Express API: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. These are inherited by prototype. There are two extension points for the Express API: 1. The global prototypes at `express.request` and `express.response`. 2. App-specific prototypes at `app.request` and `app.response`. diff --git a/src/content/docs/zh-tw/4x/guide/routing.mdx b/src/content/docs/zh-tw/4x/guide/routing.mdx index 71afe6a955..c626f1f74a 100644 --- a/src/content/docs/zh-tw/4x/guide/routing.mdx +++ b/src/content/docs/zh-tw/4x/guide/routing.mdx @@ -13,7 +13,7 @@ for example, `app.get()` to handle GET requests and `app.post` to handle POST re see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function. +In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function. These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. In fact, the routing methods can have more than one callback function as arguments. With multiple callback functions, it is important to provide `next` as an argument to the callback function and then call `next()` within the body of the function to hand off control @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. For a full list, see [app.METHOD](/api/application#appmethod). -There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Route paths -Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions. +Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -235,6 +235,26 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => { }); ``` +A wildcard (`*`) on its own matches anything at its position, including entire subpaths. For example, this route path will match `/file/style.css` as well as `/file/javascripts/jquery.js`. Wildcards are unnamed, so the matched value is available as `req.params[0]` instead of a named parameter. + +```js +app.get('/file/*', (req, res) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/file/*', (req: Request, res: Response) => { + // GET /file/javascripts/jquery.js + res.send(req.params[0]); + // => 'javascripts/jquery.js' +}); +``` + ### Route paths based on regular expressions @@ -348,6 +368,14 @@ characters with an additional backslash, for example `\d+`. The [`*`](https://github.com/expressjs/express/issues/2495) character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. +Unlike named route parameters, wildcard (`*`) matches in [string patterns](#route-paths-based-on-string-patterns) and capture groups in regular expressions are unnamed: their values are available by position, as `req.params[0]`, `req.params[1]`, and so on. + +``` +Route path: /file/*/size/* +Request URL: http://localhost:3000/file/javascripts/jquery.js/size/large +req.params: { "0": "javascripts/jquery.js", "1": "large" } +``` + ## Route handlers You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route. @@ -387,7 +415,7 @@ In this example: Route handlers can be in the form of a function, an array of functions, or combinations of both, as shown in the following examples. -A single callback function can handle a route. For example: +More than one callback function can handle a route (make sure you specify the `next` object). For example: ```js app.get('/example/a', (req, res) => { @@ -403,7 +431,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -More than one callback function can handle a route (make sure you specify the `next` object). For example: +A combination of independent functions and arrays of functions can handle a route. For example: ```js app.get( @@ -527,7 +555,7 @@ app.get( ## Response methods -The methods on the response object (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging.| Method | Description | Method | Description | | ----------------------------------------------- | ------------------------------------------------------------------------------------- | @@ -544,9 +572,9 @@ The methods on the response object (`res`) in the following table can send a res ## app.route() You can create chainable route handlers for a route path by using `app.route()`. -Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router). -Here is an example of chained route handlers that are defined by using `app.route()`. +|## app.route()You can create chainable route handlers for a rou ```js app @@ -580,9 +608,9 @@ app ## express.Router -Use the `express.Router` class to create modular, mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app". +Use the `express.Router` class to create modular, mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app".The following example creates a router as a module, loads a middlew -The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app. +The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app.Create a router file named `birds.js` in the app directory, with th Create a router file named `birds.js` in the app directory, with the following content: @@ -677,7 +705,7 @@ app.use('/birds', birds); The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route. -But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter). ```js const router = express.Router({ mergeParams: true }); diff --git a/src/content/docs/zh-tw/4x/guide/using-middleware.mdx b/src/content/docs/zh-tw/4x/guide/using-middleware.mdx index a0862b0b4f..2d2d18d3ca 100644 --- a/src/content/docs/zh-tw/4x/guide/using-middleware.mdx +++ b/src/content/docs/zh-tw/4x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Learn how to use middleware in Express.js applications, including a import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express is a routing and middleware web framework that has minimal functionality of its own: An Express application is essentially a series of middleware function calls. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -_Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the next middleware function in the application's request-response cycle. The next middleware function is commonly denoted by a variable named `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Middleware functions can perform the following tasks: - Execute any code. -- Make changes to the request and the response objects. +- Modify the request and response objects. - End the request-response cycle. -- Call the next middleware function in the stack. +- Pass control to the next middleware function. -If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging. An Express application can use the following types of middleware: @@ -27,14 +32,15 @@ An Express application can use the following types of middleware: - [Built-in middleware](#middleware.built-in) - [Third-party middleware](#middleware.third-party) -You can load application-level and router-level middleware with an optional mount path. -You can also load a series of middleware functions together, which creates a sub-stack of the middleware system at a mount point. +You can load application-level and router-level middleware with an optional mount path. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Application-level middleware -Bind application-level middleware to an instance of the [app object](/api#app) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -This example shows a middleware function with no mount path. The function is executed every time the app receives a request. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -This example shows a middleware function mounted on the `/user/:id` path. The function is executed for any type of -HTTP request on the `/user/:id` path. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` -This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path. +### Route handlers + +This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path: ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Here is an example of loading a series of middleware functions at a mount point, with a mount path. -It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the `/user/:id` path. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. +### Multiple route handlers -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -To skip the rest of the middleware functions from a router middleware stack, call `next('route')` to pass control to the next route. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ To skip the rest of the middleware functions from a router middleware stack, cal -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Middleware can also be declared in an array for reusability. +### Reusable middleware arrays -This example shows an array with a middleware sub-stack that handles GET requests to the `/user/:id` path +Middleware functions can also be grouped into arrays for better reusability. This example shows an array with a middleware sub-stack that handles GET requests to the `/user/:id` path: ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,19 +280,25 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Router-level middleware -Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); ``` +```ts +import express from 'express'; + +const router = express.Router(); +``` + Load router-level middleware by using the `router.use()` and `router.METHOD()` functions. The following example code replicates the middleware system that is shown above for application-level middleware, by using router-level middleware: @@ -313,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -363,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -413,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -434,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -To skip the rest of the router's middleware functions, call `next('router')` -to pass control back out of the router instance. +### Skipping out of a router -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. + +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -506,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Error-handling middleware - - -Error-handling middleware always takes _four_ arguments. You must provide four arguments to -identify it as an error-handling middleware function. Even if you don't need to use the `next` -object, you must specify it to maintain the signature. Otherwise, the `next` object will be -interpreted as regular middleware and will fail to handle errors. - - - Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature `(err, req, res, next)`: ```js @@ -533,7 +543,20 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For details about error-handling middleware, see: [Error handling](/guide/error-handling). + + +Error-handling middleware always takes _four_ arguments. You must provide four arguments to +identify it as an error-handling middleware function. Even if you don't need to use the `next` +object, you must specify it to maintain the signature. Otherwise, the `next` object will be +interpreted as regular middleware and will fail to handle errors. + + + + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## Built-in middleware @@ -544,6 +567,8 @@ Express has the following built-in middleware functions: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. - [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. **NOTE: Available with Express 4.17.0+** +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. **NOTE: Available with Express 4.17.0+** - [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** ## Third-party middleware @@ -552,7 +577,7 @@ Use third-party middleware to add functionality to Express apps. Install the Node.js module for the required functionality, then load it in your app at the application level or at the router level. -The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`. +The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`: @@ -585,4 +610,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -For a partial list of third-party middleware functions that are commonly used with Express, see: [Third-party middleware](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/zh-tw/4x/guide/using-template-engines.mdx b/src/content/docs/zh-tw/4x/guide/using-template-engines.mdx index 18284a627d..d097a96420 100644 --- a/src/content/docs/zh-tw/4x/guide/using-template-engines.mdx +++ b/src/content/docs/zh-tw/4x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Using template engines with Express -description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ A _template engine_ enables you to use static template files in your application variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page. -The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it also supports [Handlebars](https://www.npmjs.com/package/handlebars), and [EJS](https://www.npmjs.com/package/ejs), among others. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, the directory where the template files are located. Eg: `app.set('views', './views')`. This defaults to the `views` directory in the application root directory. - `view engine`, the template engine to use. For example, to use the Pug template engine: `app.set('view engine', 'pug')`. -Then install the corresponding template engine npm package; for example to install Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ which `res.render()` calls to render the template code. Some template engines do not follow this convention. The [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) library follows this convention by mapping all of the popular Node.js template engines, and therefore works seamlessly within Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/zh-tw/4x/guide/writing-middleware.mdx b/src/content/docs/zh-tw/4x/guide/writing-middleware.mdx index 37b925af2c..650570479e 100644 --- a/src/content/docs/zh-tw/4x/guide/writing-middleware.mdx +++ b/src/content/docs/zh-tw/4x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Learn how to write custom middleware functions for Express.js appli --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the `next` function in the application's request-response cycle. The `next` function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware. @@ -200,7 +201,7 @@ The middleware function `myLogger` simply prints a message, then passes on the r ### Middleware function requestTime Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` -to the request object. +to the [request object](/api/request). @@ -420,9 +421,13 @@ functions. -Because you have access to the request object, the response object, the next middleware function in the stack, and the whole Node.js API, the possibilities with middleware functions are endless. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -For more information about Express middleware, see: [Using Express middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Configurable middleware diff --git a/src/content/docs/zh-tw/4x/starter/basic-routing.mdx b/src/content/docs/zh-tw/4x/starter/basic-routing.mdx index ef4d06764d..b75994c83a 100644 --- a/src/content/docs/zh-tw/4x/starter/basic-routing.mdx +++ b/src/content/docs/zh-tw/4x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Learn the fundamentals of routing in Express.js applications, inclu --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -For more details about routing, see the [routing guide](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/zh-tw/4x/starter/faq.mdx b/src/content/docs/zh-tw/4x/starter/faq.mdx index 89c07591cf..1931f06ae1 100644 --- a/src/content/docs/zh-tw/4x/starter/faq.mdx +++ b/src/content/docs/zh-tw/4x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## How should I structure my application? There is no definitive answer to this question. The answer depends @@ -42,7 +44,11 @@ To normalize template engine interfaces and caching, see the [consolidate.js](https://github.com/visionmedia/consolidate.js) project for support. Unlisted template engines might still support the Express signature. -For more information, see [Using template engines with Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## How do I handle 404 responses? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For more information, see [Error handling](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## How do I render plain HTML? diff --git a/src/content/docs/zh-tw/4x/starter/installing.mdx b/src/content/docs/zh-tw/4x/starter/installing.mdx index 2b040edf10..1b0a095d6a 100644 --- a/src/content/docs/zh-tw/4x/starter/installing.mdx +++ b/src/content/docs/zh-tw/4x/starter/installing.mdx @@ -79,7 +79,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/zh-tw/4x/starter/static-files.mdx b/src/content/docs/zh-tw/4x/starter/static-files.mdx index 15a901a994..73872efd6c 100644 --- a/src/content/docs/zh-tw/4x/starter/static-files.mdx +++ b/src/content/docs/zh-tw/4x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Understand how to serve static files like images, CSS, and JavaScri --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; To serve static files such as images, CSS files, and JavaScript files, use the `express.static` built-in middleware function in Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + For more details about the `serve-static` function and its options, see [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/docs/zh-tw/5x/guide/debugging.mdx b/src/content/docs/zh-tw/5x/guide/debugging.mdx index 24bbce3510..62b6303e5e 100644 --- a/src/content/docs/zh-tw/5x/guide/debugging.mdx +++ b/src/content/docs/zh-tw/5x/guide/debugging.mdx @@ -4,104 +4,218 @@ description: Learn how to enable and use debugging logs in Express.js applicatio --- import Alert from '@components/primitives/Alert/Alert.astro'; +import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -To see all the internal logs used in Express, set the `DEBUG` environment variable to -`express:*` when launching your app. +To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*,router,router:*` when launching your app. Routing is handled by the separate [router](https://github.com/pillarjs/router) package, so its logs live under the `router` namespace and are not included in `express:*`. ```bash -$ DEBUG=express:* node index.js +$ DEBUG=express:*,router,router:* node index.js ``` On Windows, use the corresponding command. ```bash -> $env:DEBUG = "express:*"; node index.js +> $env:DEBUG = "express:*,router,router:*"; node index.js ``` -Running this command on the default app generated by the [express generator](/starter/generator) prints the following output: +Running this command on a small app with a JSON body parser and a mounted router prints the following output: + +```cjs title="index.cjs" +const express = require('express'); + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` + +```mjs title="index.mjs" +import express from 'express'; + +const app = express(); + +app.use(express.json()); + +const users = express.Router(); +users.get('/', (req, res) => { + res.json([]); +}); + +app.use('/users', users); + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(3000); +``` ```bash -$ DEBUG=express:* node ./bin/www - express:router:route new / +0ms - express:router:layer new / +1ms - express:router:route get / +1ms - express:router:layer new / +0ms - express:router:route new / +1ms - express:router:layer new / +0ms - express:router:route get / +0ms - express:router:layer new / +0ms - express:application compile etag weak +1ms - express:application compile query parser extended +0ms - express:application compile trust proxy false +0ms - express:application booting in development mode +1ms - express:router use / query +0ms - express:router:layer new / +0ms - express:router use / expressInit +0ms - express:router:layer new / +0ms - express:router use / favicon +1ms - express:router:layer new / +0ms - express:router use / logger +0ms - express:router:layer new / +0ms - express:router use / jsonParser +0ms - express:router:layer new / +1ms - express:router use / urlencodedParser +0ms - express:router:layer new / +0ms - express:router use / cookieParser +0ms - express:router:layer new / +0ms - express:router use / stylus +90ms - express:router:layer new / +0ms - express:router use / serveStatic +0ms - express:router:layer new / +0ms - express:router use / router +0ms - express:router:layer new / +1ms - express:router use /users router +0ms - express:router:layer new /users +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms - express:router use / &lt;anonymous&gt; +0ms - express:router:layer new / +0ms +$ DEBUG=express:*,router,router:* node index.js + express:application set "x-powered-by" to true +0ms + express:application set "etag" to 'weak' +3ms + express:application set "etag fn" to [Function: generateETag] +0ms + express:application set "env" to 'development' +1ms + express:application set "query parser" to 'simple' +0ms + express:application set "query parser fn" to [Function: parse] +0ms + express:application set "subdomain offset" to 2 +1ms + express:application set "trust proxy" to false +0ms + express:application set "trust proxy fn" to [Function: trustNone] +1ms + express:application booting in development mode +0ms + express:application set "view" to [Function: View] +0ms + express:application set "views" to '/projects/example/views' +1ms + express:application set "jsonp callback name" to 'callback' +0ms + router use '/' jsonParser +0ms + router:layer new '/' +0ms + router:route new '/' +0ms + router:layer new '/' +3ms + router:route get / +0ms + router:layer new '/' +1ms + router use '/users' router +4ms + router:layer new '/users' +0ms + router:route new '/' +1ms + router:layer new '/' +0ms + router:route get / +1ms + router:layer new '/' +1ms ``` When a request is then made to the app, you will see the logs specified in the Express code: ```bash - express:router dispatching GET / +4h - express:router query : / +2ms - express:router expressInit : / +0ms - express:router favicon : / +0ms - express:router logger : / +1ms - express:router jsonParser : / +0ms - express:router urlencodedParser : / +1ms - express:router cookieParser : / +0ms - express:router stylus : / +0ms - express:router serveStatic : / +2ms - express:router router : / +2ms - express:router dispatching GET / +1ms - express:view lookup "index.pug" +338ms - express:view stat "/projects/example/views/index.pug" +0ms - express:view render "/projects/example/views/index.pug" +1ms + router dispatching GET /users +712ms + router jsonParser : /users +1ms + router trim prefix (/users) from url /users +2ms + router router /users : /users +0ms + router dispatching GET / +0ms +``` + +To see the logs only from the router implementation, set the value of `DEBUG` to `router,router:*`. Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on. + +## Using `debug` in your own code + +The same [debug](https://www.npmjs.com/package/debug) module that Express uses internally is available for your application code. Install it, create one or more loggers scoped to a namespace of your choosing, and call them wherever you would otherwise use `console.log`: + + + +```cjs title="index.cjs" +const express = require('express'); +const debug = require('debug')('myapp:server'); + +const app = express(); + +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); + +app.listen(3000, () => { + debug('listening on port 3000'); +}); ``` -To see the logs only from the router implementation, set the value of `DEBUG` to `express:router`. Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on. +```mjs title="index.mjs" +import express from 'express'; +import debugModule from 'debug'; -## Applications generated by `express` +const debug = debugModule('myapp:server'); +const app = express(); -An application generated by the `express` command uses the `debug` module and its debug namespace is scoped to the name of the application. +app.get('/', (req, res) => { + debug('handling request from %s', req.ip); + res.send('Hello World!'); +}); -For example, if you generated the app with `$ express sample-app`, you can enable the debug statements with the following command: +app.listen(3000, () => { + debug('listening on port 3000'); +}); +``` + +These statements print nothing by default. Enable them through the same `DEBUG` environment variable, using your own namespace: ```bash -$ DEBUG=sample-app:* node ./bin/www +$ DEBUG=myapp:* node index.js ``` You can specify more than one debug namespace by assigning a comma-separated list of names: ```bash -$ DEBUG=http,mail,express:* node index.js +$ DEBUG=myapp:*,router node index.js ``` +## Setting DEBUG in your IDE + +The `DEBUG` environment variable can be set by any process launcher that supports environment variables, including the run and debug configurations of your IDE. For example, in VS Code you can set it in the `env` property of a launch configuration: + +```json title=".vscode/launch.json" +{ + "type": "node", + "request": "launch", + "name": "Launch Express app", + "program": "${workspaceFolder}/index.js", + "env": { "DEBUG": "express:*,router,router:*" } +} +``` + +See [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) for the full list of launch options. + +## Using the Node.js inspector + +Debug logs show what the app did; for stepping through your code with breakpoints, use the built-in Node.js inspector. Start your app with the `--inspect` flag: + +```bash +$ node --inspect index.js +``` + +Then attach a debugging client, such as Chrome DevTools (open `chrome://inspect`), VS Code, or any other inspector-capable tool, to set breakpoints in your route handlers and middleware, step through code, and inspect variables. + +If you need to debug something that happens during startup, use `--inspect-brk` instead, which pauses execution on the first line until a debugger attaches. See the [Node.js debugging guide](https://nodejs.org/learn/getting-started/debugging) for details. + +## Debugging the HTTP layer + +Express runs on top of the Node.js `http` module, which has its own debugging facilities that work with any Express app. + +Setting the `NODE_DEBUG` environment variable to `http` makes Node.js print internal logs from the HTTP layer, such as connection handling and socket events: + +```bash +$ NODE_DEBUG=http node index.js +``` + +You can combine it with other subsystems, such as `net` or `stream`, in a comma-separated list. Be aware that this output can expose sensitive data such as authentication headers, so use it only in development. + +## Diagnostics channels + +Node.js publishes an event for every HTTP request through the [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html#http) module, which you can subscribe to without patching Express or adding middleware: + +```cjs title="index.cjs" +const { subscribe } = require('node:diagnostics_channel'); + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +```mjs title="index.mjs" +import { subscribe } from 'node:diagnostics_channel'; + +subscribe('http.server.request.start', ({ request }) => { + console.log(`${request.method} ${request.url}`); +}); +``` + +Other built-in channels cover the rest of the request lifecycle, such as `http.server.response.finish`, and the client side of `http.request` calls. See the [diagnostics_channel documentation](https://nodejs.org/api/diagnostics_channel.html#http) for the full list. + ## Advanced options When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: diff --git a/src/content/docs/zh-tw/5x/guide/error-handling.mdx b/src/content/docs/zh-tw/5x/guide/error-handling.mdx index f933d9e32b..a5b202c501 100644 --- a/src/content/docs/zh-tw/5x/guide/error-handling.mdx +++ b/src/content/docs/zh-tw/5x/guide/error-handling.mdx @@ -14,6 +14,8 @@ handler so you don't need to write your own to get started. It's important to ensure that Express catches all errors that occur while running route handlers and middleware. +### Errors in synchronous code + Errors that occur in synchronous code inside route handlers and middleware require no extra work. If synchronous code throws an error, then Express will catch and process it. For example: @@ -32,51 +34,24 @@ app.get('/', (req: Request, res: Response) => { }); ``` -For errors returned from asynchronous functions invoked by route handlers -and middleware, you must pass them to the `next()` function, where Express will -catch and process them. For example: - -```js -app.get('/', (req, res, next) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` +### Errors in asynchronous code -```ts -import { type Request, type Response, type NextFunction } from 'express'; - -app.get('/', (req: Request, res: Response, next: NextFunction) => { - fs.readFile('/file-does-not-exist', (err, data) => { - if (err) { - next(err); // Pass errors to Express. - } else { - res.send(data); - } - }); -}); -``` - -Starting with Express 5, route handlers and middleware that return a Promise -will call `next(value)` automatically when they reject or throw an error. -For example: +The recommended way to write asynchronous handlers is with `async` functions. +Route handlers and middleware that return a Promise call `next(value)` +automatically when they reject or throw an error, and `async` functions always +return a Promise, so their errors reach Express with no extra work. For example: ```js -app.get('/user/:id', async (req, res, next) => { +app.get('/user/:id', async (req, res) => { const user = await getUserById(req.params.id); res.send(user); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', async (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', async (req: Request, res: Response) => { const user = await getUserById(req.params.id); res.send(user); }); @@ -90,49 +65,41 @@ If you pass anything to the `next()` function (except the string `'route'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. -If the callback in a sequence provides no data, only errors, you can simplify -this code as follows: +### Working with promise chains + +If you build a promise chain instead of using an `async` function, return the +promise from the handler and Express will likewise call `next` automatically +when it rejects: ```js -app.get('/', [ - function (req, res, next) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req, res) { - res.send('OK'); - }, -]); +app.get('/', (req, res) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/', [ - function (req: Request, res: Response, next: NextFunction) { - fs.writeFile('/inaccessible-path', 'data', next); - }, - function (req: Request, res: Response) { - res.send('OK'); - }, -]); +app.get('/', (req: Request, res: Response) => { + return Promise.resolve().then(() => { + throw new Error('BROKEN'); // Express will catch this and call next. + }); +}); ``` -In the above example, `next` is provided as the callback for `fs.writeFile`, -which is called with or without errors. If there is no error, the second -handler is executed, otherwise Express catches and processes the error. - -You must catch errors that occur in asynchronous code invoked by route handlers or -middleware and pass them to Express for processing. For example: +If the promise is not returned, Express does not know it exists, and you must +route the error yourself by providing `next` as the final catch handler. +Without it, the rejection would be unhandled and crash the process: ```js app.get('/', (req, res, next) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` @@ -140,31 +107,32 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - setTimeout(() => { - try { + Promise.resolve() + .then(() => { throw new Error('BROKEN'); - } catch (err) { - next(err); - } - }, 100); + }) + .catch(next); // Errors will be passed to Express. }); ``` -The above example uses a `try...catch` block to catch errors in the -asynchronous code and pass them to Express. If the `try...catch` -block were omitted, Express would not catch the error since it is not part of the synchronous -handler code. +This works because if a callback in the promise chain throws, the chain turns that exception into a rejection, which travels down to the final `.catch`. There, `.catch` calls its handler with the error as the first argument, which is exactly the argument `next` expects, so the error reaches Express. -Use promises to avoid the overhead of the `try...catch` block or when using functions -that return promises. For example: +### Working with callback APIs + +Errors produced by callback-based APIs, such as those in `node:fs`, are not +thrown and are not part of any promise. The callback receives them as its first +argument, and you must pass them to the `next()` function yourself, where +Express will catch and process them. For example: ```js app.get('/', (req, res, next) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` @@ -172,17 +140,46 @@ app.get('/', (req, res, next) => { import { type Request, type Response, type NextFunction } from 'express'; app.get('/', (req: Request, res: Response, next: NextFunction) => { - Promise.resolve() - .then(() => { - throw new Error('BROKEN'); - }) - .catch(next); // Errors will be passed to Express. + fs.readFile('/file-does-not-exist', (err, data) => { + if (err) { + next(err); // Pass errors to Express. + } else { + res.send(data); + } + }); }); ``` -Since promises automatically catch both synchronous errors and rejected promises, -you can simply provide `next` as the final catch handler and Express will catch errors, -because the catch handler is given the error as the first argument. +If the callback in a sequence provides no data, only errors, you can simplify +this code as follows: + +```js +app.get('/', [ + function (req, res, next) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req, res) { + res.send('OK'); + }, +]); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', [ + function (req: Request, res: Response, next: NextFunction) { + fs.writeFile('/inaccessible-path', 'data', next); + }, + function (req: Request, res: Response) { + res.send('OK'); + }, +]); +``` + +In the above example, `next` is provided as the callback for `fs.writeFile`, +which is called with or without errors. If there is no error, the second +handler is executed, otherwise Express catches and processes the error. You could also use a chain of handlers to rely on synchronous error catching, by reducing the asynchronous code to something trivial. For example: @@ -219,7 +216,7 @@ app.get('/', [ ]); ``` -The above example has a couple of trivial statements from the `readFile` +The above example contains a couple of trivial statements following the `readFile` call. If `readFile` causes an error, then it passes the error to Express, otherwise you quickly return to the world of synchronous error handling in the next handler in the chain. Then, the example above tries to process the data. If this fails, then the @@ -227,6 +224,41 @@ synchronous error handler will catch it. If you had done this processing inside the `readFile` callback, then the application might exit and the Express error handlers would not run. +Finally, for asynchronous code that provides no error-first callback, such as a +timer, catch errors inside the asynchronous code itself and pass them to +Express: + +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +```ts +import { type Request, type Response, type NextFunction } from 'express'; + +app.get('/', (req: Request, res: Response, next: NextFunction) => { + setTimeout(() => { + try { + throw new Error('BROKEN'); + } catch (err) { + next(err); + } + }, 100); +}); +``` + +The above example uses a `try...catch` block to catch errors in the +asynchronous code and pass them to Express. If the `try...catch` +block were omitted, Express would not catch the error since it is not part of the synchronous +handler code. + Whichever method you use, if you want Express error handlers to be called in and the application to survive, you must ensure that Express receives the error. @@ -424,7 +456,7 @@ function logErrors(err: Error, req: Request, res: Response, next: NextFunction) Also in this example, `clientErrorHandler` is defined as follows; in this case, the error is explicitly passed along to the next one. -Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. +Notice that when you do not call `next` in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. ```js function clientErrorHandler(err, req, res, next) { diff --git a/src/content/docs/zh-tw/5x/guide/overriding-express-api.mdx b/src/content/docs/zh-tw/5x/guide/overriding-express-api.mdx index 54cef9edbc..c6afcac28b 100644 --- a/src/content/docs/zh-tw/5x/guide/overriding-express-api.mdx +++ b/src/content/docs/zh-tw/5x/guide/overriding-express-api.mdx @@ -5,7 +5,7 @@ description: Discover how to customize and extend the Express.js API by overridi import Alert from '@components/primitives/Alert/Alert.astro'; -The Express API consists of various methods and properties on the request and response objects. These are inherited by prototype. There are two extension points for the Express API: +The Express API consists of various methods and properties on the [request](/api/request) and [response](/api/response) objects. These are inherited by prototype. There are two extension points for the Express API: 1. The global prototypes at `express.request` and `express.response`. 2. App-specific prototypes at `app.request` and `app.response`. diff --git a/src/content/docs/zh-tw/5x/guide/routing.mdx b/src/content/docs/zh-tw/5x/guide/routing.mdx index aafdbb401e..2a83152fb9 100644 --- a/src/content/docs/zh-tw/5x/guide/routing.mdx +++ b/src/content/docs/zh-tw/5x/guide/routing.mdx @@ -13,7 +13,7 @@ for example, `app.get()` to handle GET requests and `app.post` to handle POST re see [app.METHOD](/api/application#appmethod). You can also use [app.all()](/api/application#appall) to handle all HTTP methods and [app.use()](/api/application#appuse) to specify middleware as the callback function (See [Using middleware](/guide/using-middleware) for details). -These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function. +In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function. These routing methods specify a callback function (sometimes called a "handler function") that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. In fact, the routing methods can have more than one callback function as arguments. With multiple callback functions, it is important to provide `next` as an argument to the callback function and then call `next()` within the body of the function to hand off control @@ -88,7 +88,7 @@ app.post('/', (req: Request, res: Response) => { Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. For a full list, see [app.METHOD](/api/application#appmethod). -There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). +There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `QUERY`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#httpmethods). ```js app.all('/secret', (req, res, next) => { @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => { ## Route paths -Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings or regular expressions. +Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings or regular expressions. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below. @@ -153,77 +153,9 @@ app.get('/random.text', (req: Request, res: Response) => { }); ``` -### Wildcards - -Wildcards match any path after a prefix. They must have a name, just like route parameters, and are captured as arrays of path segments. - -```js -app.get('/files/*filepath', (req, res) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { - // GET /files/images/logo.png - console.dir(req.params.filepath); - // => [ 'images', 'logo.png' ] - res.send(`File: ${req.params.filepath.join('/')}`); -}); -``` - -To also match the root path, wrap the wildcard in braces: - -```js -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req, res) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -// Matches / , /foo , /foo/bar , etc. -app.get('/{*splat}', (req: Request, res: Response) => { - // GET / => req.params.splat = [] - // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] - res.send('ok'); -}); -``` - -### Optional segments - -Use braces to define optional segments in a route path. When the segment is not present, the parameter is omitted from `req.params`. - -```js -app.get('/:file{.:ext}', (req, res) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -```ts -import { type Request, type Response } from 'express'; - -app.get('/:file{.:ext}', (req: Request, res: Response) => { - // GET /image.png => req.params = { file: 'image', ext: 'png' } - // GET /image => req.params = { file: 'image' } - res.send('ok'); -}); -``` - -The characters `?`, `+`, `*`, `[]`, and `()` are reserved and cannot be used as literal characters in route paths. Use `\` to escape them if needed. +The characters `?`, `+`, `*`, `[]`, `()`, and `!` are reserved and cannot be used as literal characters in route paths, and braces are reserved for [optional segments](#optional-segments). Use `\` to escape them if needed. @@ -259,7 +191,11 @@ app.get(/.*fly$/, (req: Request, res: Response) => { ## Route parameters -Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter specified in the path as their respective keys. +Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter specified in the path as their respective keys. They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces. + +### Named parameters + +Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below. ``` Route path: /users/:userId/books/:bookId @@ -293,7 +229,7 @@ app.get('/users/:userId/books/:bookId', sendParams); -The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]). +The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example `:"user-name"`. @@ -313,14 +249,122 @@ req.params: { "genus": "Prunus", "species": "persica" } -Regexp characters are not supported in route paths. Use an array of paths or regular expressions instead. +Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as `:userId(\d+)`. Use an array of paths or a full regular expression instead. See the [path route matching syntax](/guide/migrating-5#path-syntax) for more information. +### Wildcards + +Wildcards match any path after a prefix. Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string. + +```js +app.get('/files/*filepath', (req, res) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { + // GET /files/images/logo.png + console.dir(req.params.filepath); + // => [ 'images', 'logo.png' ] + res.send(`File: ${req.params.filepath.join('/')}`); +}); +``` + +To also match the root path, wrap the wildcard in braces: + +```js +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req, res) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +// Matches / , /foo , /foo/bar , etc. +app.get('/{*splat}', (req: Request, res: Response) => { + // GET / => req.params = {}, splat is omitted + // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] + res.send('ok'); +}); +``` + +### Optional segments + +Use braces to define optional segments in a route path. When the segment is not present, the parameter is omitted from `req.params`. + +```js +app.get('/:file{.:ext}', (req, res) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/:file{.:ext}', (req: Request, res: Response) => { + // GET /image.png => req.params = { file: 'image', ext: 'png' } + // GET /image => req.params = { file: 'image' } + res.send('ok'); +}); +``` + +The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters: + +```js +app.get('/user/\{:id}', (req, res) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req, res) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +```ts +import { type Request, type Response } from 'express'; + +app.get('/user/\{:id}', (req: Request, res: Response) => { + // GET /user/42 => req.params = { id: '42' } + // GET /user/ => req.params = {} + // GET /user => 404, only the parameter is optional + res.send('ok'); +}); + +app.get('/order{/:id}', (req: Request, res: Response) => { + // GET /order/42 => req.params = { id: '42' } + // GET /order => req.params = {}, the whole segment is optional + res.send('ok'); +}); +``` + +不要將路由路徑中斜線的位置與[`strict routing` 設定](/api/application/#application-settings)混淆,後者針對的是請求 URL:它控制以路由路徑未要求的斜線結尾的 URL 是否仍然匹配。 例如,對 `/order/` 的請求預設會匹配 `/order{/:id}` 路由,但在啟用 strict routing 時會傳回 404 錯誤;`/user/` 的結尾斜線不受影響,因為 `/user/\{:id}` 路由要求它。 上述範例中註解的所有請求無論該設定為何,行為都相同。## Route handlersYou can provide multiple callback functions that + ## Route handlers -You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route. +You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route.```js +app.get('/user/:id', (req, res, next) => { +if (req.params.i + +```` ```js app.get('/user/:id', (req, res, next) => { @@ -333,7 +377,7 @@ app.get('/user/:id', (req, res, next) => { app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0'); }); -``` +```` ```ts import { type Request, type Response, type NextFunction } from 'express'; @@ -355,15 +399,17 @@ In this example: - `GET /user/5` → handled by first route → sends "User 5" - `GET /user/0` → first route calls `next('route')`, skipping to the next matching `/user/:id` route -Route handlers can be in the form of a function, an array of functions, or combinations of both, as shown in the following examples. +Route handlers can be in the form of a function, an array of functions, or combinations of both, as shown in the following examples.A single callback function can handle a route. For example:```js + +```` -A single callback function can handle a route. For example: +More than one callback function can handle a route (make sure you specify the `next` object). ```js app.get('/example/a', (req, res) => { res.send('Hello from A!'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -373,7 +419,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -More than one callback function can handle a route (make sure you specify the `next` object). For example: +A combination of independent functions and arrays of functions can handle a route. For example: ```js app.get( @@ -403,7 +449,7 @@ app.get( ); ``` -An array of callback functions can handle a route. For example: +An array of callback functions can handle a route. ```js const cb0 = function (req, res, next) { @@ -497,26 +543,32 @@ app.get( ## Response methods -The methods on the response object (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging. +The methods on the [response object](/api/response) (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging.| Method | Description| Method | Description -| Method | Description | -| ----------------------------------------------- | ------------------------------------------------------------------------------------- | -| [res.download()](/api/response#resdownload) | Prompt a file to be downloaded. | -| [res.end()](/api/response#resend) | End the response process. | -| [res.json()](/api/response#resjson) | Send a JSON response. | -| [res.jsonp()](/api/response#resjsonp) | Send a JSON response with JSONP support. | -| [res.redirect()](/api/response#resredirect) | Redirect a request. | -| [res.render()](/api/response#resrender) | Render a view template. | -| [res.send()](/api/response#ressend) | Send a response of various types. | -| [res.sendFile()](/api/response#ressendfile) | Send a file as an octet stream. | -| [res.sendStatus()](/api/response#ressendstatus) | Set the response status code and send its string representation as the response body. | +| | | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/api/response#resdownload) | Prompt a file to be downloaded. | +| [res.end()](/api/response#resend) | End the response process. | +| [res.json()](/api/response#resjson) | Send a JSON response. | +| [res.jsonp()](/api/response#resjsonp) | Send a JSON response with JSONP support. | +| | Redirect a request. | +| [res.render()](/api/response#resrender) | Render a view template. | +| [res.send()](/api/response#ressend) | Send a response of various types. | +| [res.sendFile()](/api/response#ressendfile) | Send a file as an octet stream. | +| [res.sendStatus()](/api/response#ressendstatus) | Set the response status code and send its string representation as the response body. \|## app.route()You can create chainable route handlers for a rou | ## app.route() You can create chainable route handlers for a route path by using `app.route()`. -Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/api/router). +Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router).Here is an example of chained route handlers that are defined by us + +|## app.route()You can create chainable route handlers for a rou```js +app +.route('/book') +.get((req, res) => { +res.send('Ge -Here is an example of chained route handlers that are defined by using `app.route()`. +```` ```js app @@ -530,7 +582,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -550,9 +602,9 @@ app ## express.Router -Use the `express.Router` class to create modular, mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app". +Use the `express.Router` class to create modular, mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app".The following example creates a router as a module, loads a middlewThe following example creates a router as a module, loads a middlew -The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app. +The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app.Create a router file named `birds.js` in the app directory, with thCreate a router file named `birds.js` in the app directory, with th Create a router file named `birds.js` in the app directory, with the following content: @@ -645,10 +697,13 @@ import birds from './birds'; app.use('/birds', birds); ``` -The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route. +The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route.But if the parent route `/birds` has path parameters, it will not b -But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse). +But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter).```js +const router = express.Router({ mergeParams: true }); + +```` ```js const router = express.Router({ mergeParams: true }); -``` +```` diff --git a/src/content/docs/zh-tw/5x/guide/using-middleware.mdx b/src/content/docs/zh-tw/5x/guide/using-middleware.mdx index 282234bb84..53c84df475 100644 --- a/src/content/docs/zh-tw/5x/guide/using-middleware.mdx +++ b/src/content/docs/zh-tw/5x/guide/using-middleware.mdx @@ -5,19 +5,24 @@ description: Learn how to use middleware in Express.js applications, including a import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; -Express is a routing and middleware web framework that has minimal functionality of its own: An Express application is essentially a series of middleware function calls. +Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle. -_Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the next middleware function in the application's request-response cycle. The next middleware function is commonly denoted by a variable named `next`. +_Middleware_ functions are functions that have access to: + +- The [request object](/api/request) (`req`) +- The [response object](/api/response) (`res`) +- The next middleware function in the application's request-response cycle, commonly named `next` Middleware functions can perform the following tasks: - Execute any code. -- Make changes to the request and the response objects. +- Modify the request and response objects. - End the request-response cycle. -- Call the next middleware function in the stack. +- Pass control to the next middleware function. -If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging. +If a middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging. An Express application can use the following types of middleware: @@ -27,14 +32,15 @@ An Express application can use the following types of middleware: - [Built-in middleware](#middleware.built-in) - [Third-party middleware](#middleware.third-party) -You can load application-level and router-level middleware with an optional mount path. -You can also load a series of middleware functions together, which creates a sub-stack of the middleware system at a mount point. +You can load application-level and router-level middleware with an optional mount path. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point. ## Application-level middleware -Bind application-level middleware to an instance of the [app object](/api#app) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase. +Bind application-level middleware to an instance of the [app object](/api/application) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the lowercase HTTP method of the request that the middleware function handles, such as `get`, `post`, `put`, or `delete`. + +### Middleware without a mount path -This example shows a middleware function with no mount path. The function is executed every time the app receives a request. +The following middleware function runs every time the app receives a request: ```cjs title="index.cjs" const express = require('express'); @@ -68,8 +74,9 @@ app.use((req: Request, res: Response, next: NextFunction) => { }); ``` -This example shows a middleware function mounted on the `/user/:id` path. The function is executed for any type of -HTTP request on the `/user/:id` path. +### Middleware mounted on a path + +The following middleware function runs for any type of HTTP request on the `/user/:id` path: ```js app.use('/user/:id', (req, res, next) => { @@ -87,24 +94,27 @@ app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { }); ``` -This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path. +### Route handlers + +This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path: ```js -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('USER'); }); ``` ```ts -import { type Request, type Response, type NextFunction } from 'express'; +import { type Request, type Response } from 'express'; -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('USER'); }); ``` -Here is an example of loading a series of middleware functions at a mount point, with a mount path. -It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the `/user/:id` path. +### Middleware sub-stacks + +Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the `/user/:id` path: ```js app.use( @@ -136,9 +146,9 @@ app.use( ); ``` -Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. +### Multiple route handlers -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. ```js app.get( @@ -147,13 +157,13 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req, res, next) => { + (req, res) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send(req.params.id); }); ``` @@ -167,18 +177,20 @@ app.get( console.log('ID:', req.params.id); next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { res.send('User Info'); } ); // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send(req.params.id); }); ``` -To skip the rest of the middleware functions from a router middleware stack, call `next('route')` to pass control to the next route. +### Skipping to the next route + +Call `next('route')` to skip the remaining middleware functions in a router middleware stack and pass control to the next route. @@ -187,7 +199,7 @@ To skip the rest of the middleware functions from a router middleware stack, cal -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +In the following example, if the user ID is `0`, the first handler skips to the next route, which sends a special response: ```js app.get( @@ -198,14 +210,14 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req, res, next) => { +app.get('/user/:id', (req, res) => { res.send('special'); }); ``` @@ -221,21 +233,21 @@ app.get( // otherwise pass the control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // send a regular response res.send('regular'); } ); // handler for the /user/:id path, which sends a special response -app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', (req: Request, res: Response) => { res.send('special'); }); ``` -Middleware can also be declared in an array for reusability. +### Reusable middleware arrays -This example shows an array with a middleware sub-stack that handles GET requests to the `/user/:id` path +Middleware functions can also be grouped into arrays for better reusability. This example shows an array with a middleware sub-stack that handles GET requests to the `/user/:id` path: ```js function logOriginalUrl(req, res, next) { @@ -249,7 +261,7 @@ function logMethod(req, res, next) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req, res, next) => { +app.get('/user/:id', logStuff, (req, res) => { res.send('User Info'); }); ``` @@ -268,14 +280,14 @@ function logMethod(req: Request, res: Response, next: NextFunction) { } const logStuff = [logOriginalUrl, logMethod]; -app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { +app.get('/user/:id', logStuff, (req: Request, res: Response) => { res.send('User Info'); }); ``` ## Router-level middleware -Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of `express.Router()`. +Router-level middleware works the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router(); @@ -319,19 +331,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -369,19 +381,19 @@ router.use( router.get( '/user/:id', (req, res, next) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req, res, next) => { + (req, res) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req, res, next) => { +router.get('/user/:id', (req, res) => { console.log(req.params.id); res.render('special'); }); @@ -419,19 +431,19 @@ router.use( router.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { - // if the user ID is 0, skip to the next router + // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route'); // otherwise pass control to the next middleware function in this stack else next(); }, - (req: Request, res: Response, next: NextFunction) => { + (req: Request, res: Response) => { // render a regular page res.render('regular'); } ); // handler for the /user/:id path, which renders a special page -router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { +router.get('/user/:id', (req: Request, res: Response) => { console.log(req.params.id); res.render('special'); }); @@ -440,10 +452,11 @@ router.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { app.use('/', router); ``` -To skip the rest of the router's middleware functions, call `next('router')` -to pass control back out of the router instance. +### Skipping out of a router + +Use `next('router')` to skip the rest of the router's middleware functions and pass control back out of the router instance. -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. +In the following example, the router only responds when the request includes an `x-auth` header. Otherwise, `next('router')` exits the router and the app responds with a 401 status: ```cjs title="index.cjs" const express = require('express'); @@ -512,15 +525,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## Error-handling middleware - - -Error-handling middleware always takes _four_ arguments. You must provide four arguments to -identify it as an error-handling middleware function. Even if you don't need to use the `next` -object, you must specify it to maintain the signature. Otherwise, the `next` object will be -interpreted as regular middleware and will fail to handle errors. - - - Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature `(err, req, res, next)`: ```js @@ -539,18 +543,30 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For details about error-handling middleware, see: [Error handling](/guide/error-handling). + -## Built-in middleware +Error-handling middleware always takes _four_ arguments. You must provide four arguments to +identify it as an error-handling middleware function. Even if you don't need to use the `next` +object, you must specify it to maintain the signature. Otherwise, the `next` object will be +interpreted as regular middleware and will fail to handle errors. + + + + -Starting with version 4.x, Express no longer depends on [Connect](https://github.com/senchalabs/connect). The middleware -functions that were previously included with Express are now in separate modules; see [the list of middleware functions](https://github.com/senchalabs/connect#middleware). +For more information, see the [Error handling](/guide/error-handling) guide. + + + +## Built-in middleware Express has the following built-in middleware functions: - [express.static](/api/express/#expressstatic) serves static assets such as HTML files, images, and so on. -- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** -- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** +- [express.json](/api/express/#expressjson) parses incoming requests with JSON payloads. +- [express.raw](/api/express/#expressraw) parses incoming requests with Buffer payloads. +- [express.text](/api/express/#expresstext) parses incoming requests with text payloads. +- [express.urlencoded](/api/express/#expressurlencoded) parses incoming requests with URL-encoded payloads. ## Third-party middleware @@ -558,7 +574,7 @@ Use third-party middleware to add functionality to Express apps. Install the Node.js module for the required functionality, then load it in your app at the application level or at the router level. -The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`. +The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`: @@ -591,4 +607,8 @@ const app: Express = express(); app.use(cookieParser()); ``` -For a partial list of third-party middleware functions that are commonly used with Express, see: [Third-party middleware](/resources/middleware). + + +For a partial list of third-party middleware functions that are commonly used with Express, see the [Third-party middleware](/resources/middleware) page. + + diff --git a/src/content/docs/zh-tw/5x/guide/using-template-engines.mdx b/src/content/docs/zh-tw/5x/guide/using-template-engines.mdx index 18284a627d..d097a96420 100644 --- a/src/content/docs/zh-tw/5x/guide/using-template-engines.mdx +++ b/src/content/docs/zh-tw/5x/guide/using-template-engines.mdx @@ -1,6 +1,6 @@ --- title: Using template engines with Express -description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. +description: Discover how to integrate and use template engines like Pug, Handlebars-compatible engines, and EJS with Express.js to render dynamic HTML pages efficiently. --- import Alert from '@components/primitives/Alert/Alert.astro'; @@ -10,15 +10,15 @@ A _template engine_ enables you to use static template files in your application variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page. -The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it also supports [Handlebars](https://www.npmjs.com/package/handlebars), and [EJS](https://www.npmjs.com/package/ejs), among others. +The [Express application generator](/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it can generate apps configured for Handlebars-compatible engines such as [hbs](https://www.npmjs.com/package/hbs), [EJS](https://www.npmjs.com/package/ejs), among others. -To render template files, set the following [application setting properties](/api/application/#appset), in the default `app.js` created by the generator: +For apps created by the generator, these settings are added to the generated `app.js`. For apps you create without the generator, set the following [application setting properties](/api/application/#appset) yourself: - `views`, the directory where the template files are located. Eg: `app.set('views', './views')`. This defaults to the `views` directory in the application root directory. - `view engine`, the template engine to use. For example, to use the Pug template engine: `app.set('view engine', 'pug')`. -Then install the corresponding template engine npm package; for example to install Pug: +Then install the corresponding Express-compatible template engine npm package; for example to install Pug: @@ -28,6 +28,7 @@ which `res.render()` calls to render the template code. Some template engines do not follow this convention. The [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) library follows this convention by mapping all of the popular Node.js template engines, and therefore works seamlessly within Express. +For example, install [hbs](https://www.npmjs.com/package/hbs) or any other Express-compatible Handlebars view engine instead of the raw `handlebars` package by itself. diff --git a/src/content/docs/zh-tw/5x/guide/writing-middleware.mdx b/src/content/docs/zh-tw/5x/guide/writing-middleware.mdx index b3a0c5d9c4..f164a2d7ca 100644 --- a/src/content/docs/zh-tw/5x/guide/writing-middleware.mdx +++ b/src/content/docs/zh-tw/5x/guide/writing-middleware.mdx @@ -4,6 +4,7 @@ description: Learn how to write custom middleware functions for Express.js appli --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Middleware_ functions are functions that have access to the [request object](/api#req) (`req`), the [response object](/api#res) (`res`), and the `next` function in the application's request-response cycle. The `next` function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware. @@ -171,7 +172,7 @@ The middleware function `myLogger` simply prints a message, then passes on the r ### Middleware function requestTime Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` -to the request object. +to the [request object](/api/request). @@ -391,9 +392,13 @@ functions. -Because you have access to the request object, the response object, the next middleware function in the stack, and the whole Node.js API, the possibilities with middleware functions are endless. +Because you have access to the [request object](/api/request), the [response object](/api/response), the next middleware function in the stack, and the whole [Node.js API](https://nodejs.org/api/), the possibilities with middleware functions are endless. -For more information about Express middleware, see: [Using Express middleware](/guide/using-middleware). + + +For more information about Express middleware, see the [Using Express middleware](/guide/using-middleware) guide. + + ## Configurable middleware diff --git a/src/content/docs/zh-tw/5x/starter/basic-routing.mdx b/src/content/docs/zh-tw/5x/starter/basic-routing.mdx index ef4d06764d..b75994c83a 100644 --- a/src/content/docs/zh-tw/5x/starter/basic-routing.mdx +++ b/src/content/docs/zh-tw/5x/starter/basic-routing.mdx @@ -4,6 +4,7 @@ description: Learn the fundamentals of routing in Express.js applications, inclu --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; _Routing_ refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on). @@ -96,4 +97,8 @@ app.delete('/user', (req: Request, res: Response) => { }); ``` -For more details about routing, see the [routing guide](/guide/routing). + + +For more details about routing, see the [Routing](/guide/routing) guide. + + diff --git a/src/content/docs/zh-tw/5x/starter/faq.mdx b/src/content/docs/zh-tw/5x/starter/faq.mdx index b75a4aeabc..194db26b08 100644 --- a/src/content/docs/zh-tw/5x/starter/faq.mdx +++ b/src/content/docs/zh-tw/5x/starter/faq.mdx @@ -3,6 +3,8 @@ title: FAQ description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## How should I structure my application? There is no definitive answer to this question. The answer depends @@ -42,7 +44,11 @@ To normalize template engine interfaces and caching, see the [consolidate.js](https://github.com/visionmedia/consolidate.js) project for support. Unlisted template engines might still support the Express signature. -For more information, see [Using template engines with Express](/guide/using-template-engines). + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. + + ## How do I handle 404 responses? @@ -92,7 +98,11 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { }); ``` -For more information, see [Error handling](/guide/error-handling). + + +For more information, see the [Error handling](/guide/error-handling) guide. + + ## How do I render plain HTML? diff --git a/src/content/docs/zh-tw/5x/starter/installing.mdx b/src/content/docs/zh-tw/5x/starter/installing.mdx index 27a32d62dd..e320885aca 100644 --- a/src/content/docs/zh-tw/5x/starter/installing.mdx +++ b/src/content/docs/zh-tw/5x/starter/installing.mdx @@ -70,7 +70,7 @@ non-erasable syntax (such as `enum`s, namespaces, and parameter properties) that } ``` -Write your application in TypeScript, annotating the request and response objects: +Write your application in TypeScript, annotating the [request](/api/request) and [response](/api/response) objects: ```ts title="src/app.ts" import express, { type Express, type Request, type Response } from 'express'; diff --git a/src/content/docs/zh-tw/5x/starter/static-files.mdx b/src/content/docs/zh-tw/5x/starter/static-files.mdx index 15a901a994..73872efd6c 100644 --- a/src/content/docs/zh-tw/5x/starter/static-files.mdx +++ b/src/content/docs/zh-tw/5x/starter/static-files.mdx @@ -4,6 +4,7 @@ description: Understand how to serve static files like images, CSS, and JavaScri --- import Alert from '@components/primitives/Alert/Alert.astro'; +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; To serve static files such as images, CSS files, and JavaScript files, use the `express.static` built-in middleware function in Express. @@ -85,4 +86,8 @@ import path from 'path'; app.use('/static', express.static(path.join(__dirname, 'public'))); ``` + + For more details about the `serve-static` function and its options, see [serve-static](/resources/middleware/serve-static). + + diff --git a/src/content/pages/de/advanced/best-practice-performance.mdx b/src/content/pages/de/advanced/best-practice-performance.mdx new file mode 100644 index 0000000000..8dea8296bf --- /dev/null +++ b/src/content/pages/de/advanced/best-practice-performance.mdx @@ -0,0 +1,333 @@ +--- +title: 'Production best practices: performance and reliability' +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. +--- + +This article discusses performance and reliability best practices for Express applications deployed to production. + +This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: [things to do in your code](#things-to-do-in-your-code) (the dev part), and [things to do in your environment / setup](#things-to-do-in-your-environment--setup) (the ops part). + +## Things to do in your code + +Here are some things you can do in your code to improve your application's performance. + +### Use gzip compression + +Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. Zum Beispiel: + +```cjs title="index.cjs" +const compression = require('compression'); +const express = require('express'); +const app = express(); + +app.use(compression()); +``` + +```mjs title="index.mjs" +import compression from 'compression'; +import express from 'express'; + +const app = express(); + +app.use(compression()); +``` + +For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) in the Nginx documentation. + +### Don't use synchronous functions + +Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production. + +Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup. + +You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli.html#--trace-sync-io) for more information. + +### Do logging correctly + +In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console.html#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. + +#### For debugging + +If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you? + +#### For app activity + +If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available. + +### Handle exceptions properly + +Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly. + +To ensure you handle all exceptions, use the following techniques: + +- [Use try-catch](#use-try-catch) +- [Use promises](#use-promises) + +Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain. + +For more on the fundamentals of error handling, see: + +- [Error Handling in Node.js](https://web.archive.org/web/20210619211351/https://www.joyent.com/node-js/production/design/errors) + +#### Use try-catch + +Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below. + +Here is an example of using try-catch to handle a potential process-crashing exception. +This middleware function accepts a query field parameter named "params" that is a JSON object. + +```js +app.get('/search', (req, res) => { + // Simulating async operation + setImmediate(() => { + const jsonStr = req.query.params; + try { + const jsonObj = JSON.parse(jsonStr); + res.send('Success'); + } catch (e) { + res.status(400).send('Invalid JSON string'); + } + }); +}); +``` + +However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions. + +#### Use promises + +When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)` + +```js +app.get('/', async (req, res, next) => { + const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error. + + res.send(data); +}); + +app.use((err, req, res, next) => { + res.status(err.status ?? 500).send({ error: err.message }); +}); +``` + +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: + +```js +app.use(async (req, res, next) => { + req.locals.user = await getUser(req); + + next(); // This will be called if the promise does not throw an error. +}); +``` + +Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware. + +#### What not to do + +One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable. + +Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process.html#event-uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error. + +We also don't recommend using [domains](https://nodejs.org/api/domain.html). It generally doesn't solve the problem and is a deprecated module. + +### Use worker threads for CPU-intensive tasks + +Node.js runs your JavaScript on a single thread, so a CPU-intensive operation (such as image processing, parsing or transforming large payloads, or cryptographic operations) can block the event loop and slow down every request your Express app is handling. If your app does CPU-bound work, you can run it in [worker threads](https://nodejs.org/api/worker_threads.html), which execute JavaScript in parallel within the same process, keeping the main thread free to serve requests. + +Each worker thread runs in its own JavaScript engine instance, so the data you pass to it through `workerData` or `postMessage` is copied, not shared. Copying large payloads has a cost of its own, which you can avoid by transferring objects such as `ArrayBuffer`s or by sharing memory explicitly with `SharedArrayBuffer`. Worker threads are not a replacement for [running your app in a cluster](#run-your-app-in-a-cluster), which scales your app across CPU cores by running multiple instances of it in separate processes. + +This example offloads an image-resizing task to a worker, where `resize-worker.js` receives the image via `workerData` and posts the result back when it's done: + +```js +const { Worker } = require('node:worker_threads'); + +app.post('/resize', (req, res, next) => { + const worker = new Worker('./resize-worker.js', { workerData: req.body.image }); + + worker.once('message', (result) => res.send(result)); + worker.once('error', next); +}); +``` + +Note that this example is kept simple for illustration: creating a worker thread is relatively expensive, so [the Node.js documentation recommends using a pool of workers](https://nodejs.org/api/worker_threads.html#worker-threads) instead of spawning a new one for every request. Create a fixed pool of workers at startup and dispatch tasks to them as requests come in, for example with a library like [piscina](https://www.npmjs.com/package/piscina): + +```js +const path = require('node:path'); +const Piscina = require('piscina'); + +const pool = new Piscina({ filename: path.resolve(__dirname, 'resize-worker.js') }); + +app.post('/resize', async (req, res, next) => { + try { + res.send(await pool.run(req.body.image)); + } catch (err) { + next(err); + } +}); +``` + +Here `resize-worker.js` simply exports the function to run in the pool, and piscina takes care of creating the workers, queueing tasks, and reusing threads across requests. + +For more guidance on keeping the event loop responsive, including when offloading work is worth its communication costs, see [Don't Block the Event Loop](https://nodejs.org/learn/asynchronous-work/dont-block-the-event-loop) in the Node.js documentation. + +## Things to do in your environment / setup + +Here are some things you can do in your system environment to improve your app's performance. + +### Set NODE_ENV to "production" + +The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. + +Setting NODE_ENV to "production" makes Express: + +- Cache view templates. +- Cache CSS files generated from CSS extensions. +- Generate less verbose error messages. + +[Tests indicate](https://web.archive.org/web/20250814011110/https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three! + +If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. + +In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here. + +With systemd, use the `Environment` directive in your unit file. Zum Beispiel: + +```sh + +Environment=NODE_ENV=production +``` + +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). + +### Use the latest LTS version of Node.js + +Running your app on a recent Node.js release is one of the easiest ways to improve performance. Each new version of Node.js ships with cumulative improvements to the V8 JavaScript engine and the runtime itself, so the same Express app can handle significantly more requests simply by upgrading. Benchmarks such as NodeSource's [Node.js Performance Report](https://nodesource.com/pages/content-node-performance-report-wb.html) show how much throughput can improve from one Node.js version to the next. For production, use the latest [LTS release](https://nodejs.org/en/about/previous-releases) of Node.js, and keep it up to date as new versions come out. + +### Ensure your app automatically restarts + +In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by: + +- Using a process manager to restart the app (and Node) when it crashes. +- Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager. + +Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart. + +#### Use a process manager + +In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime. + +In addition to restarting your app when it crashes, a process manager can enable you to: + +- Gain insights into runtime performance and resource consumption. +- Modify settings dynamically to improve performance. +- Control clustering (pm2). + +Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management. + +#### Use an init system + +The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd). + +There are two ways to use init systems with your Express app: + +- Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach. +- Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager. + +##### Systemd + +Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system. + +A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `\` for your system and app: + +```sh +[Unit] +Description= + +[Service] +Type=simple +ExecStart=/usr/local/bin/node +WorkingDirectory= + +User=nobody +Group=nogroup + + +Environment=NODE_ENV=production + + +LimitNOFILE=infinity + + +LimitCORE=infinity + +StandardInput=null +StandardOutput=syslog +StandardError=syslog +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +For more information on systemd, see the [systemd reference (man page)](https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html). + +### Run your app in a cluster + +In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. + +![Balancing between application instances using the cluster API](/images/clustering.png) + +IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](https://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers. + +In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork(). + +#### Using Node's cluster module + +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. + +#### Using PM2 + +If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like). + +When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app. + +To enable cluster mode, start your application like so: + +```bash + +$ pm2 start npm --name my-app -i 4 -- start + +$ pm2 start npm --name my-app -i max -- start +``` + +This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start. + +Once running, the application can be scaled like so: + +```bash + +$ pm2 scale my-app +3 + +$ pm2 scale my-app 2 +``` + +For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. + +### Cache request results + +Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly. + +Use a caching server like [Varnish](https://www.varnish.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/c/nginx-caching)) to greatly improve the speed and performance of your app. + +### Use a load balancer + +No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance. + +A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). + +With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/). + +### Use a reverse proxy + +A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things. + +Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/src/content/pages/de/advanced/best-practice-security.mdx b/src/content/pages/de/advanced/best-practice-security.mdx index 52d205e86a..0d2d2b1750 100644 --- a/src/content/pages/de/advanced/best-practice-security.mdx +++ b/src/content/pages/de/advanced/best-practice-security.mdx @@ -64,7 +64,7 @@ Hier ist ein Beispiel für die Überprüfung von URLs, bevor `res.redirect` oder ```js app.use((req, res) => { try { - if (new Url(req.query.url).host !== 'example.com') { + if (new URL(req.query.url).host !== 'example.com') { return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`); } } catch (e) { diff --git a/src/content/pages/de/advanced/healthcheck-graceful-shutdown.mdx b/src/content/pages/de/advanced/healthcheck-graceful-shutdown.mdx new file mode 100644 index 0000000000..a8375714eb --- /dev/null +++ b/src/content/pages/de/advanced/healthcheck-graceful-shutdown.mdx @@ -0,0 +1,28 @@ +--- +title: Health Checks and Graceful Shutdown +description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes. +--- + +## Graceful shutdown + +When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit. + +### Beispiel + +```js +const server = app.listen(port); + +process.on('SIGTERM', () => { + debug('SIGTERM signal received: closing HTTP server'); + server.close(() => { + debug('HTTP server closed'); + }); +}); +``` + +## Health checks + +A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes//): + +- `liveness`, that determines when to restart a container. +- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers. diff --git a/src/content/pages/de/resources/middleware/body-parser.mdx b/src/content/pages/de/resources/middleware/body-parser.mdx index 0dcfdf32a2..68a0da0aa0 100644 --- a/src/content/pages/de/resources/middleware/body-parser.mdx +++ b/src/content/pages/de/resources/middleware/body-parser.mdx @@ -1,5 +1,5 @@ --- -title: Body-Parser Middleware +title: body-parser Middleware description: Node.js Körper parsen Middleware --- @@ -20,7 +20,7 @@ unter der `req.body` Eigenschaft. **Note** As `req.body`'s shape is based on user-controlled input, all properties and values in this object are untrusted and should be validated -before trusting. Zum Beispiel `req.body.foo. oString()` kann auf mehreren +before trusting. Zum Beispiel `req.body.foo.toString()` kann auf mehreren Wegen fehlschlagen, zum Beispiel könnte die `foo` Eigenschaft nicht vorhanden sein oder kein String sein, und `toString` sind möglicherweise keine Funktion und stattdessen eine Zeichenkette oder andere Benutzereingabe. @@ -96,22 +96,22 @@ Objekt nach der Middleware (d.h. `req.body`) gefüllt. The `json` function takes an optional `options` object that may contain any of the following keys: -##### standard Zeichensatz +##### defaultCharset Geben Sie den Standardzeichensatz für den json-Inhalt an, wenn der Zeichensatz nicht im `Content-Type`-Header der Anfrage angegeben ist. Standard ist `utf-8`. -##### aufblasen +##### inflate Wenn auf `true` gesetzt, dann werden die entschärften (komprimierten) Körper aufgeblasen; wenn `false` wird, werden die entschärften Körper abgelehnt. Standard ist `true`. -##### begrenzen +##### limit Steuert die maximale Größe des Request-Bodys. Wenn dies eine Zahl ist, gibt der Wert die Anzahl der Bytes an; wenn es sich um einen String handelt, wird der Wert an die [bytes](https://www.npmjs.com/package/bytes) Bibliothek zum Parsen übergeben. Standard -auf `'100kb`. +ist `'100kb'`. > Es wird empfohlen, nicht ein sehr hohes Limit zu konfigurieren und den Standardwert wann immer möglich zu verwenden. Das Erlauben größerer Payloads erhöht die Speicherauslastung aufgrund der Ressourcen, die für die Dekodierung und Transformation benötigt werden, und es kann auch zu längeren Reaktionszeiten führen, wenn mehr Daten verarbeitet werden. Mit „sehr hoch“ meinen wir Werte über dem Standardwert, zum Beispiel mit einer Nutzlast von 5 MB oder mehr können bereits damit begonnen werden, diese Risiken einzuführen. Bei den Standardlimits treten diese Probleme nicht auf. @@ -121,12 +121,12 @@ Die Option `reviver` wird als zweites Argument direkt an `JSON.parse` übergeben. You can find more information on this argument [in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#the_reviver_parameter). -##### strikt +##### strict When set to `true`, will only accept arrays and objects; when `false` will accept anything `JSON.parse` accepts. Standard ist `true`. -##### typ +##### type Die Option `type` wird verwendet, um festzustellen, welcher Medientyp die Middleware parst. Diese Option kann ein String, ein Array von Strings oder eine Funktion sein. Wenn nicht @@ -137,7 +137,7 @@ ein Mime-Typ mit einem Platzhalter (wie `*/*` oder `*/json`). Wenn eine Funktion als `fn(req)` aufgerufen und die Anfrage wird geparst, wenn sie einen wahrhaften Wert zurückgibt. Standard ist `application/json`. -##### überprüfen +##### verify Die `verify` Option, falls vorhanden, wird als `verify(req, res, buf, encoding)` aufgerufen, wobei `buf` ein `Buffer` des Roh-Request-Body ist und `encoding` die @@ -159,21 +159,21 @@ des Körpers sein. The `raw` function takes an optional `options` object that may contain any of the following keys: -##### aufblasen +##### inflate Wenn auf `true` gesetzt, dann werden die entschärften (komprimierten) Körper aufgeblasen; wenn `false` wird, werden die entschärften Körper abgelehnt. Standard ist `true`. -##### begrenzen +##### limit Steuert die maximale Größe des Request-Bodys. Wenn dies eine Zahl ist, gibt der Wert die Anzahl der Bytes an; wenn es sich um einen String handelt, wird der Wert an die [bytes](https://www.npmjs.com/package/bytes) Bibliothek zum Parsen übergeben. Standard -auf `'100kb`. +ist `'100kb'`. > Es wird empfohlen, nicht ein sehr hohes Limit zu konfigurieren und den Standardwert wann immer möglich zu verwenden. Das Erlauben größerer Payloads erhöht die Speicherauslastung aufgrund der Ressourcen, die für die Dekodierung und Transformation benötigt werden, und es kann auch zu längeren Reaktionszeiten führen, wenn mehr Daten verarbeitet werden. Mit „sehr hoch“ meinen wir Werte über dem Standardwert, zum Beispiel mit einer Nutzlast von 5 MB oder mehr können bereits damit begonnen werden, diese Risiken einzuführen. Bei den Standardlimits treten diese Probleme nicht auf. -##### typ +##### type Die Option `type` wird verwendet, um festzustellen, welcher Medientyp die Middleware parst. Diese Option kann ein String, ein Array von Strings oder eine Funktion sein. @@ -185,7 +185,7 @@ kann ein Name der Erweiterung sein (wie `bin`), ein Mime-Typ (wie and the request is parsed if it returns a truthy value. Standardmäßig `application/octet-stream`. -##### überprüfen +##### verify Die `verify` Option, falls vorhanden, wird als `verify(req, res, buf, encoding)` aufgerufen, wobei `buf` ein `Buffer` des Roh-Request-Body ist und `encoding` die @@ -207,26 +207,26 @@ Körpers sein. The `text` function takes an optional `options` object that may contain any of the following keys: -##### standard Zeichensatz +##### defaultCharset Geben Sie den Standardzeichensatz für den Textinhalt an, wenn der Zeichensatz nicht im `Content-Type`-Header der Anfrage angegeben ist. Standard ist `utf-8`. -##### aufblasen +##### inflate Wenn auf `true` gesetzt, dann werden die entschärften (komprimierten) Körper aufgeblasen; wenn `false` wird, werden die entschärften Körper abgelehnt. Standard ist `true`. -##### begrenzen +##### limit Steuert die maximale Größe des Request-Bodys. Wenn dies eine Zahl ist, gibt der Wert die Anzahl der Bytes an; wenn es sich um einen String handelt, wird der Wert an die [bytes](https://www.npmjs.com/package/bytes) Bibliothek zum Parsen übergeben. Standard -auf `'100kb`. +ist `'100kb'`. > Es wird empfohlen, nicht ein sehr hohes Limit zu konfigurieren und den Standardwert wann immer möglich zu verwenden. Das Erlauben größerer Payloads erhöht die Speicherauslastung aufgrund der Ressourcen, die für die Dekodierung und Transformation benötigt werden, und es kann auch zu längeren Reaktionszeiten führen, wenn mehr Daten verarbeitet werden. Mit „sehr hoch“ meinen wir Werte über dem Standardwert, zum Beispiel mit einer Nutzlast von 5 MB oder mehr können bereits damit begonnen werden, diese Risiken einzuführen. Bei den Standardlimits treten diese Probleme nicht auf. -##### typ +##### type Die Option `type` wird verwendet, um festzustellen, welcher Medientyp die Middleware parst. Diese Option kann ein String, ein Array von Strings oder eine Funktion sein. Wenn nicht @@ -237,7 +237,7 @@ tippen Sie mit einem Platzhalter (wie `*/*` oder `text/*`). Wenn eine Funktion, Option als `fn(req)` aufgerufen und die Anfrage geparst, wenn sie einen truthy Wert zurückgibt. Standard ist `text/plain`. -##### überprüfen +##### verify Die `verify` Option, falls vorhanden, wird als `verify(req, res, buf, encoding)` aufgerufen, wobei `buf` ein `Buffer` des Roh-Request-Body ist und `encoding` die @@ -260,7 +260,7 @@ enthalten, wobei der Wert ein String oder ein Array sein kann (wenn `extended` The `urlencoded` function takes an optional `options` object that may contain any of the following keys: -##### erweitert +##### extended Die "extended" Syntax erlaubt es, reiche Objekte und Arrays in das URL-kodierte Format zu kodieren. Dies ermöglicht eine JSON-ähnliche Erfahrung mit URL-kodiert. For @@ -269,17 +269,17 @@ library. Standard ist `false`. -##### aufblasen +##### inflate Wenn auf `true` gesetzt, dann werden die entschärften (komprimierten) Körper aufgeblasen; wenn `false` wird, werden die entschärften Körper abgelehnt. Standard ist `true`. -##### begrenzen +##### limit Steuert die maximale Größe des Request-Bodys. Wenn dies eine Zahl ist, gibt der Wert die Anzahl der Bytes an; wenn es sich um einen String handelt, wird der Wert an die [bytes](https://www.npmjs.com/package/bytes) Bibliothek zum Parsen übergeben. Standard -auf `'100kb`. +ist `'100kb'`. > Es wird empfohlen, nicht ein sehr hohes Limit zu konfigurieren und den Standardwert wann immer möglich zu verwenden. Das Erlauben größerer Payloads erhöht die Speicherauslastung aufgrund der Ressourcen, die für die Dekodierung und Transformation benötigt werden, und es kann auch zu längeren Reaktionszeiten führen, wenn mehr Daten verarbeitet werden. Mit „sehr hoch“ meinen wir Werte über dem Standardwert, zum Beispiel mit einer Nutzlast von 5 MB oder mehr können bereits damit begonnen werden, diese Risiken einzuführen. Bei den Standardlimits treten diese Probleme nicht auf. @@ -289,7 +289,7 @@ Die Option `parameterLimit` steuert die maximale Anzahl an Parametern, die in den URL-kodierten Daten erlaubt. If a request contains more parameters than this value, a 413 will be returned to the client. Standard ist `1000`. -##### typ +##### type Die Option `type` wird verwendet, um festzustellen, welcher Medientyp die Middleware parst. Diese Option kann ein String, ein Array von Strings oder eine Funktion sein. Wenn nicht @@ -301,13 +301,13 @@ ein Name der Erweiterung sein (wie `urlencoded`), ein Mime-Typ (wie `fn(req)` aufgerufen und die Anfrage wird geparst, wenn sie einen truthy-Wert zurückgibt. Standardmäßig auf `application/x-www-form-urlencoded`. -##### überprüfen +##### verify Die `verify` Option, falls vorhanden, wird als `verify(req, res, buf, encoding)` aufgerufen, wobei `buf` ein `Buffer` des Roh-Request-Body ist und `encoding` die Kodierung der Anfrage. Das Parsen kann durch Werfen eines Fehlers abgebrochen werden. -##### standard Zeichensatz +##### defaultCharset Der voreingestellte Zeichensatz, als der nicht im Inhaltstyp angegeben wird. Muss entweder `utf-8` oder `iso-8859-1` sein. Standard ist `utf-8`. @@ -318,12 +318,12 @@ Gibt an, ob der Wert des Parameters `utf8` als Zeichensatz Vorrang haben soll. Es erfordert, dass das Formular einen Parameter namens `utf8` mit einem Wert von `\ ` enthält. Standard ist `false`. -##### interpretieren NumericEntities +##### interpretNumericEntities Gibt an, ob numerische Entitäten wie `☺` beim Parsen eines iso-8859-1 dekodiert werden sollen. Standard ist `false`. -##### tiefe +##### depth Die Option `depth` wird benutzt um die maximale Tiefe der `qs` Bibliothek zu konfigurieren, wenn `extended` `true` ist. Dies erlaubt Ihnen, die Anzahl der geparsten Schlüssel zu begrenzen und kann nützlich sein, um bestimmte Arten von Missbrauch zu verhindern. Standard ist `32`. Es wird empfohlen, diesen Wert so niedrig wie möglich zu halten. @@ -340,87 +340,87 @@ des gelesenen Textes, falls verfügbar. Die folgenden sind die häufigen Fehler erzeugt, obwohl jeder Fehler aus verschiedenen Gründen durch kommen kann. -### Inhaltskodierung nicht unterstützt +### content encoding unsupported Dieser Fehler tritt auf, wenn die Anfrage einen `Content-Encoding`-Header hatte, der eine Kodierung enthielt, aber die Option "inflation" wurde auf `false` gesetzt. Die Eigenschaft `status` ist auf `415` gesetzt, die Eigenschaft `type` ist auf -`'encoding gesetzt. nsupported'` und die Eigenschaft `charset` wird auf die nicht unterstützte Kodierung +`'encoding.unsupported'` und die Eigenschaft `charset` wird auf die nicht unterstützte Kodierung gesetzt. -### Entitäts-Parse fehlgeschlagen +### entity parse failed This error will occur when the request contained an entity that could not be parsed by the middleware. Die Eigenschaft `status` ist auf `400` gesetzt, die Eigenschaft `type` -ist auf `'entity.parse gesetzt. ailed'` und die Eigenschaft `body` ist auf +ist auf `'entity.parse.failed'` und die Eigenschaft `body` ist auf gesetzt, der Entitätswert der fehlgeschlagen ist. -### Entität verifizieren fehlgeschlagen +### entity verify failed Dieser Fehler tritt auf, wenn die Anfrage eine Entität enthielt, die nicht sein konnte durch die definierte `verify` Option zu verifizieren. Die Eigenschaft `status` ist -auf `403` gesetzt, die Eigenschaft `type` ist auf `'entity.verify gesetzt. ailed'` und die Eigenschaft +auf `403` gesetzt, die Eigenschaft `type` ist auf `'entity.verify.failed'` und die Eigenschaft `body` wird auf den Entitätswert gesetzt, der bei der Überprüfung fehlgeschlagen ist. -### abgebrochen +### request aborted Dieser Fehler tritt auf, wenn die Anfrage vom Client abgebrochen wird, bevor der Inhalt -gelesen wird. Die Eigenschaft `empfangen` wird auf die Anzahl der empfangenen -Bytes gesetzt, bevor die Anfrage abgebrochen wurde und die Eigenschaft `erwartet` ist +gelesen wird. Die Eigenschaft `received` wird auf die Anzahl der empfangenen +Bytes gesetzt, bevor die Anfrage abgebrochen wurde und die Eigenschaft `expected` ist auf die Anzahl der erwarteten Bytes gesetzt. Die Eigenschaft `status` wurde auf `400` -gesetzt und `type` auf \`'request.aborted'gesetzt. +gesetzt und `type` auf `'request.aborted'` gesetzt. -### Anfrage Entität zu groß +### request entity too large Dieser Fehler tritt auf, wenn die Größe des Request-Bodys größer ist als die Option "limit" . Die Eigenschaft `limit` wird auf das Bytelimit gesetzt und die Eigenschaft `length` wird auf die Länge des Anfragekörpers gesetzt. Die Eigenschaft `status` ist -auf `413` gesetzt und die Eigenschaft `type` auf \`'entity.too.large' gesetzt. +auf `413` gesetzt und die Eigenschaft `type` auf `'entity.too.large'` gesetzt. -### Anfragengröße stimmt nicht mit der Länge des Inhalts überein +### request size did not match content length Dieser Fehler tritt auf, wenn die Länge der Anfrage nicht mit der Länge von übereinstimmt, dem `Content-Length` Header. Dies tritt in der Regel auf, wenn die Anfrage fehlerhaft formatiert ist, typischerweise wenn der `Content-Length` Header auf der Grundlage von Zeichen anstelle von Bytes berechnet wurde. Die Eigenschaft `status` ist auf `400` gesetzt und die Eigenschaft `type` -ist auf \`'request.size.invalid'gesetzt. +ist auf `'request.size.invalid'` gesetzt. -### streamkodierung sollte nicht gesetzt werden +### stream encoding should not be set Dieser Fehler tritt auf, wenn etwas als `req.setEncoding` Methode vor auf diese Middleware lautete. Dieses Modul funktioniert nur auf Bytes und Sie können bei Verwendung dieses Moduls nicht `req.setEncoding` aufrufen. Die Eigenschaft `status` ist auf -`500` gesetzt und die Eigenschaft `type` ist auf \`'stream.encoding.set' gesetzt. +`500` gesetzt und die Eigenschaft `type` ist auf `'stream.encoding.set'` gesetzt. -### stream ist nicht lesbar +### stream is not readable Dieser Fehler tritt auf, wenn die Anfrage nicht mehr lesbar ist, wenn diese Middleware versucht, sie zu lesen. Dies bedeutet typischerweise etwas anderes als eine Middleware von dieses Modul liest bereits den Request-Body und die Middleware wurde auch auf konfiguriert, die gleiche Anfrage zu lesen. Die Eigenschaft `status` ist auf `500` gesetzt und die Eigenschaft `type` -ist auf \`'stream.not.readable' gesetzt. +ist auf `'stream.not.readable'` gesetzt. -### zu viele Parameter +### too many parameters Dieser Fehler tritt auf, wenn der Inhalt der Anfrage den konfigurierten `parameterLimit` für den `urlencoded` Parser übersteigt. Die Eigenschaft `status` ist auf -`413` gesetzt und die Eigenschaft `type` ist auf `'parameters.too.many` gesetzt. +`413` gesetzt und die Eigenschaft `type` ist auf `'parameters.too.many'` gesetzt. -### nicht unterstütztes Zeichensatz "BOGUS" +### unsupported charset "BOGUS" Dieser Fehler tritt auf, wenn die Anfrage einen Zeichensatz-Parameter im `Content-Type` Header hatte aber das Modul `iconv-lite` unterstützt es nicht oder der Parser unterstützt es nicht. Der Zeichensatz ist sowohl in der Nachricht als auch in wie in der Eigenschaft `charset` enthalten. Die Eigenschaft `status` ist auf `415` gesetzt, die Eigenschaft -`type` ist auf `'-Zeichensatz gesetzt. nsupported'` und die Eigenschaft `charset` +`type` ist auf `'charset.unsupported'` und die Eigenschaft `charset` wird auf den Zeichensatz gesetzt, der nicht unterstützt wird. -### nicht unterstützte Inhaltskodierung "bogus" +### unsupported content encoding "bogus" Dieser Fehler tritt auf, wenn die Anfrage einen `Content-Encoding`-Header hatte, der eine nicht unterstützte Kodierung enthielt. Die Kodierung ist sowohl in der Nachricht als auch in der Eigenschaft `encoding` enthalten. Die Eigenschaft `status` ist auf `415` gesetzt, -die Eigenschaft `type` ist auf `'encoding gesetzt. nsupported'` und die Eigenschaft `encoding` +die Eigenschaft `type` ist auf `'encoding.unsupported'` gesetzt und die Eigenschaft `encoding` wird auf die nicht unterstützte Kodierung gesetzt. ### Die Eingabe hat die Tiefe überschritten @@ -511,5 +511,5 @@ app.use(bodyParser.text({ type: 'text/html' })); [MIT](https://github.com/expressjs/body-parser/blob/HEAD/LICENSE) [npm-url]: https://npmjs.com/package/body-parser -[ossf-Scorecard-Abzeichen]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge -[ossf-Punkte-Visualisierer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser +[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser diff --git a/src/content/pages/de/resources/middleware/compression.mdx b/src/content/pages/de/resources/middleware/compression.mdx index bfa04fd300..e07438e922 100644 --- a/src/content/pages/de/resources/middleware/compression.mdx +++ b/src/content/pages/de/resources/middleware/compression.mdx @@ -1,5 +1,5 @@ --- -title: komprimierte Middleware +title: compression Middleware description: Node.js Komprimierungs-Middleware --- @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa @@ -45,11 +45,11 @@ Dies ist ein [Node.js](https://nodejs.org/en/) Modul über die var compression = require('compression'); ``` -### komprimieren ([options]) +### compression([options]) Gibt die Komprimierung Middleware mit den angegebenen `options` zurück. Die Middleware wird versuchen, Antwortkörper für alle Anfragen zu komprimieren, die durch -die Middleware durchlaufen, basierend auf den angegebenen `Optionen`. +die Middleware durchlaufen, basierend auf den angegebenen `options`. Diese Middleware wird niemals Antworten komprimieren, die einen `Cache-Control` Header mit der [`no-transform` Direktive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4), @@ -70,9 +70,9 @@ Standard: `zlib.constants.Z_DEFAULT_CHUNK`, oder `16384`. Siehe [Node.js Dokumentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning) bezüglich der Verwendung. -##### filtern +##### filter -Typ: `Funktion` +Typ: `Function` Eine Funktion, um zu entscheiden, ob die Antwort für Komprimierung in Betracht gezogen werden soll. Diese Funktion wird als `filter(req, res)` aufgerufen und wird voraussichtlich @@ -82,7 +82,7 @@ die Antwort zu komprimieren. Die Standard-Filterfunktion verwendet das [compressible](https://www.npmjs.com/package/compressible) Modul, um festzustellen, ob `res.getHeader('Content-Type')` komprimierbar ist. -##### Level +##### level Typ: `Number`
Standard: `zlib.constants.Z_DEFAULT_COMPRESSION`, oder `-1` @@ -122,13 +122,13 @@ Level). Siehe [Node.js Dokumentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning) bezüglich der Verwendung. -##### brodeli +##### brotli Typ: `Object` Dies gibt die Optionen für die Konfiguration von Brotli an. Siehe [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) für eine vollständige Liste der verfügbaren Optionen. -##### strategie +##### strategy Typ: `Number`
Standard: `zlib.constants.Z_DEFAULT_STRATEGY` @@ -153,7 +153,7 @@ is not set appropriately. **Hinweis** in der obigen Liste ist `zlib` von `zlib = require('zlib')`. -##### schwelle +##### threshold Typ: `Number` oder `String`
Standard: `1kb` @@ -175,7 +175,7 @@ Standard: `zlib.constants.Z_DEFAULT_WINDOWBITS`, oder `15` Siehe [Node.js Dokumentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning) bezüglich der Verwendung. -##### Encoding durchsetzen +##### enforceEncoding Typ: `String`
Standard: `identity` @@ -213,7 +213,7 @@ Dieses Modul fügt eine `res.flush()` Methode hinzu, um die teilweise komprimier ## Beispiele -### ausdrücken +### express Wenn Sie dieses Modul mit Ausdrücken verwenden, einfach `app.use` das Modul als hoch. Anfragen, die durch die Middleware gehen, werden komprimiert. @@ -312,6 +312,6 @@ Siehe [Mitwirkende Anleitung](https://github.com/expressjs/express/blob/master/C [npm-url]: https://npmjs.org/package/komprimiert [downloads-url]: https://npmcharts.com/compare/compression?minimal=true -[ossf-Scorecard-Abzeichen]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge -[ossf-Punkte-Visualisierer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression -[finanzing-url]: https://opencollective.com/express +[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression +[funding-url]: https://opencollective.com/express diff --git a/src/content/pages/de/resources/middleware/cookie-parser.mdx b/src/content/pages/de/resources/middleware/cookie-parser.mdx index 6d4079e7ad..597ba59a6c 100644 --- a/src/content/pages/de/resources/middleware/cookie-parser.mdx +++ b/src/content/pages/de/resources/middleware/cookie-parser.mdx @@ -1,5 +1,5 @@ --- -title: cookie-Parser Middleware +title: cookie-parser Middleware description: HTTP-Anfrage-Cookies analysieren --- @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa @@ -36,7 +36,7 @@ Middleware verwendet werden kann. var cookieParser = require('cookie-parser'); ``` -### cookieParser(geheim, Optionen) +### cookieParser(secret, options) Erstelle eine neue Cookie-Parser-Middleware-Funktion mit den angegebenen `secret` und `options`. @@ -47,10 +47,10 @@ Erstelle eine neue Cookie-Parser-Middleware-Funktion mit den angegebenen `secret das Cookie mit jedem Geheimnis in der Reihenfolge zu entfernen. - `options` ein Objekt, das als zweite Option an `cookie.parse` übergeben wird. Siehe [cookie](https://www.npmjs.org/package/cookie) für weitere Informationen. - - `decodieren` eine Funktion, um den Wert des Cookies zu dekodieren + - `decode` eine Funktion, um den Wert des Cookies zu dekodieren Die Middleware analysiert den `Cookie`-Header auf Anfrage und legt die Cookie-Daten -als Eigenschaft `req. ookies` und, wenn ein `secret` angegeben wurde, als +als Eigenschaft `req.cookies` und, wenn ein `secret` angegeben wurde, als die Eigenschaft `req.signedCookies`. Diese Eigenschaften sind Namen-Wert-Paare des Cookie-Namens zum Cookie-Wert. @@ -70,13 +70,13 @@ als Ergebnis von `JSON.parse` angezeigt. Wenn das Parsen fehlschlägt, bleibt de Analysieren Sie einen Cookie-Wert als JSON-Cookie. Dies gibt den geparsten JSON-Wert zurück, wenn es ein JSON-Cookie war, andernfalls wird der übergebene Wert zurückgegeben. -### cookieParser.JSONCookies(Cookies) +### cookieParser.JSONCookies(cookies) Wird ein Objekt angegeben, wird es über die Schlüssel iterieren und `JSONCookie` auf jeden Wert aufrufen, wodurch der ursprüngliche Wert durch den analysierten Wert ersetzt wird. Dies gibt das gleiche Objekt zurück, das weitergegeben wurde. -### cookieParser.signedCookie(str, geheim) +### cookieParser.signedCookie(str, secret) Parsen Sie einen Cookie-Wert als signiertes Cookie. Dies gibt den parsed unsignierten Wert zurück, wenn es ein signiertes Cookie war und die Signatur gültig war. Wenn der Wert @@ -87,7 +87,7 @@ Das `secret` Argument kann ein Array oder ein String sein. Wenn eine Zeichenkett als Geheimnis verwendet. Wenn ein Array zur Verfügung gestellt wird, wird versucht das Cookie mit jedem Geheimnis in der Reihenfolge zu entfernen. -### cookieParser.signedCookies(Cookies, geheim) +### cookieParser.signedCookies(cookies, secret) Wenn ein Objekt angegeben wird, wird dies über die Schlüssel iteriert und überprüft, ob ein signierter Cookie ist. Wenn es ein signiertes Cookie ist und die Signatur gültig ist, der Schlüssel @@ -124,4 +124,4 @@ app.listen(8080); [MIT](https://github.com/expressjs/cookie-parser/blob/HEAD/LICENSE) -[npm-url]: https://npmjs.org/package/cookie-Parser +[npm-url]: https://npmjs.org/package/cookie-parser diff --git a/src/content/pages/de/resources/middleware/cookie-session.mdx b/src/content/pages/de/resources/middleware/cookie-session.mdx index d52df385d3..11fd609d05 100644 --- a/src/content/pages/de/resources/middleware/cookie-session.mdx +++ b/src/content/pages/de/resources/middleware/cookie-session.mdx @@ -1,5 +1,5 @@ --- -title: cookie-Session Middleware +title: cookie-session Middleware description: Cookie Session Middleware --- @@ -9,8 +9,8 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa Einfache Cookie-basierte Session Middleware. @@ -36,7 +36,7 @@ zu verschlüsseln, oder stattdessen eine serverseitige Sitzung verwenden. **HINWEIS** Dieses Modul verhindert nicht das Wiederholen von Sitzungen, da das Ablaufdatum festgelegt ist, dass nur des Cookies; wenn dies ein Anliegen Ihrer Anwendung ist, können Sie ein Ablaufdatum -in `req speichern. ession` Objekt und validieren Sie es auf dem Server und implementieren Sie jede andere Logik +in `req.session` Objekt speichern und validieren Sie es auf dem Server und implementieren Sie jede andere Logik um die Session so zu erweitern, wie Ihre Anwendung es braucht. ## Installieren @@ -76,7 +76,7 @@ app.use( ); ``` -### cookieSession(Optionen) +### cookieSession(options) Erstellen Sie eine neue Cookie Session Middleware mit den bereitgestellten Optionen. Diese Middleware wird die Eigenschaft `session` an `req` anhängen, die ein Objekt zur Verfügung stellt, das @@ -86,7 +86,7 @@ in der Anfrage angegeben wurde, oder eine geladene Sitzung aus der Anfrage. Die Middleware wird automatisch einen `Set-Cookie` Header zur Antwort hinzufügen, wenn der Inhalt von `req.session` geändert wurde. _Hinweis_ dass kein `Set-Cookie` Header in der Antwort sein wird (und daher keine Sitzung für einen bestimmten Benutzer erstellt), es sei denn, es gibt -Inhalt in der Sitzung, also sollten Sie etwas zu `req. ession` sobald +Inhalt in der Sitzung, also sollten Sie etwas zu `req.session` sobald du identifizierende Daten für die Sitzung gespeichert hast. #### Optionen @@ -97,7 +97,7 @@ Cookie Session akzeptiert diese Eigenschaften im Objekt Optionen. Der Name des zu setzenden Cookies, Standardwert ist `session`. -##### tasten +##### keys Die Liste der Schlüssel, die verwendet werden sollen, um Cookies zu signieren und zu verifizieren, oder eine konfigurierte [`Keygrip`](https://www.npmjs.com/package/keygrip) Instanz. Setze Cookies sind immer @@ -105,7 +105,7 @@ signiert mit `keys[0]`, während die anderen Schlüssel für die Überprüfung g für die Schlüsselrotation erlaubt wird. If a `Keygrip` instance is provided, it can be used to change signature parameters like the algorithm of the signature. -##### geheim +##### secret Ein String, der als Einzelschlüssel verwendet wird, wenn `keys` nicht angegeben wird. @@ -122,7 +122,7 @@ Die Optionen können auch folgende enthalten (für die vollständige Liste, sieh - `path`: ein String, der den Pfad des Cookie (`/` standardmäßig anzeigt). - `domain`: ein String, der die Domain des Cookie angibt (kein Standard). - `partitioned`: ein boolescher Hinweis, ob das Cookie in Chrome für das [CHIPS Update](https://developers.google.com/privacy-sandbox/3pcd/chips) (`false` standardmäßig partitioniert werden soll). Wenn dies der Fall ist, werden Cookies von eingebetteten Websites partitioniert und nur von der gleichen obersten Ebene aus lesbar, von der aus sie erstellt wurden. -- `priority`: eine Zeichenkette, die die Cookie-Priorität angibt. Dies kann auf `'low'`, `'medium' oder `'high' gesetzt werden. +- `priority`: eine Zeichenkette, die die Cookie-Priorität angibt. Dies kann auf `'low'`, `'medium'` oder `'high'` gesetzt werden. - `sameSite`: ein boolescher oder String, der angibt, ob das Cookie ein "gleiches" Cookie ist (standardmäßig `false`). Dies kann auf `'strict'`, `'lax'`, `'none'` oder `true` gesetzt werden (die Karte auf `'strict'`) - `secure`: ein boolescher Hinweis darauf, ob das Cookie nur über HTTPS gesendet werden soll (`false` standardmäßig für HTTP, `true` standardmäßig für HTTPS). Wenn dies auf `true` und Knoten gesetzt ist. s ist nicht direkt über eine TLS-Verbindung Lesen Sie bitte, wie [Einrichten Express hinter Proxies](/guide/behind-proxies) oder das Cookie nicht korrekt gesetzt werden kann. - `httpOnly`: ein boolescher Hinweis darauf, ob das Cookie nur über HTTP(S) gesendet und nicht dem Client JavaScript zur Verfügung gestellt wird (standardmäßig `true`). @@ -133,15 +133,15 @@ Die Optionen können auch folgende enthalten (für die vollständige Liste, sieh Stellt die Sitzung für die angegebene Anfrage dar. -#### .isGeändert +#### .isChanged Ist `true` wenn die Sitzung während der Anfrage geändert wurde. -#### .isNeu +#### .isNew Ist `true` wenn die Sitzung neu ist. -#### .isbesiedelt +#### .isPopulated Legen Sie fest, ob die Sitzung mit Daten besetzt wurde oder leer ist. @@ -228,7 +228,7 @@ app.use(function (req, res, next) { Dieses Modul sendet keinen `Set-Cookie` Header, wenn sich der Inhalt der Sitzung nicht geändert hat. Dies bedeutet, dass das Ablaufdatum einer Sitzung im -Browser verlängern wird (in Reaktion auf Benutzeraktivität) ) eine Art +Browser verlängern wird (in Reaktion auf Benutzeraktivität) eine Art Änderung der Sitzung ist notwendig. ```js @@ -307,4 +307,4 @@ zu einer [alternativen Sitzungsstrategie](https://github.com/expressjs/session#c [MIT](https://github.com/expressjs/cookie-session/blob/HEAD/LICENSE) -[npm-url]: https://npmjs.org/package/cookie-Sitzung +[npm-url]: https://npmjs.org/package/cookie-session diff --git a/src/content/pages/de/resources/middleware/cors.mdx b/src/content/pages/de/resources/middleware/cors.mdx index 1d88da83c2..ce29af7e72 100644 --- a/src/content/pages/de/resources/middleware/cors.mdx +++ b/src/content/pages/de/resources/middleware/cors.mdx @@ -1,6 +1,6 @@ --- -title: cors middleware -description: Node.js CORS middleware +title: cors Middleware +description: Node.js CORS Middleware --- import MiddlewareInfo from '@components/patterns/MiddlewareInfo/MiddlewareInfo.astro'; @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa diff --git a/src/content/pages/de/resources/middleware/errorhandler.mdx b/src/content/pages/de/resources/middleware/errorhandler.mdx index 799924df63..47b47d2f8d 100644 --- a/src/content/pages/de/resources/middleware/errorhandler.mdx +++ b/src/content/pages/de/resources/middleware/errorhandler.mdx @@ -1,5 +1,5 @@ --- -title: errorhandler middleware +title: errorhandler Middleware description: Middleware für Entwicklungsfehler --- @@ -9,15 +9,15 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa Middleware für den Entwicklungs-only Fehlerhandler. Diese Middleware ist nur für eine Entwicklungsumgebung gedacht als -werden die \_full error stack Traces und die internen Details eines Objekts, das an dieses -Modul übergeben wurde, an den Client zurückgeschickt, wenn ein Fehler auftritt. +werden die _full error stack Traces und die internen Details eines Objekts, das an dieses +Modul übergeben wurde_, an den Client zurückgeschickt, wenn ein Fehler auftritt. Wenn Express ein Objekt als Fehler zur Verfügung gestellt wird, wird dieses Modul so viel über dieses Objekt wie möglich anzeigen und wird dies durch die Verwendung von Inhaltsaushandlung @@ -49,7 +49,7 @@ Dies ist ein [Node.js](https://nodejs.org/en/) Modul über die ## API -{/* eslint-deaktivieren Sie keine unbenutzten vars */} +{/* eslint-disable no-unused-vars */} ```js var errorhandler = require('errorhandler'); @@ -106,7 +106,7 @@ if (process.env.NODE_ENV === 'development') { Manchmal möchten Sie die Fehler während der Entwicklung an einen anderen Ort als STDERR ausgeben, wie zum Beispiel eine Systembenachrichtigung. -{/* Elint-Deaktiviere Handle-callback-err */} +{/* eslint-disable handle-callback-err */} ```js var connect = require('connect'); diff --git a/src/content/pages/de/resources/middleware/method-override.mdx b/src/content/pages/de/resources/middleware/method-override.mdx index b08a19cde2..557306a1e2 100644 --- a/src/content/pages/de/resources/middleware/method-override.mdx +++ b/src/content/pages/de/resources/middleware/method-override.mdx @@ -1,5 +1,5 @@ --- -title: Methode, Middleware zu überschreiben +title: method-override Middleware description: HTTP-Verben überschreiben --- @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa @@ -40,12 +40,12 @@ das `csurf` Modul verwendet werden muss). ### methodOverride(getter, Optionen) Erstelle eine neue Middleware-Funktion, um die Eigenschaft `req.method` mit einem neuen --Wert zu überschreiben. Dieser Wert wird aus dem angegebenen 'getter' gezogen. +-Wert zu überschreiben. Dieser Wert wird aus dem angegebenen `getter` gezogen. - `getter` - Der zu verwendende Getter, um die überschriebene Anfragemethode für die Anfrage aufzurufen. (Standard: `X-HTTP-Method-Override`) - `options.methods` - Die erlaubten Methoden, in denen die ursprüngliche Anfrage sein muss, um auf eine Methode zu überprüfen, die Wert überschreibt. (Standard: `['POST']`) -Wenn die gefundene Methode von node.js Core unterstützt wird, dann `req. ethod` wird auf diesen Wert +Wenn die gefundene Methode von node.js Core unterstützt wird, dann `req.method` wird auf diesen Wert gesetzt, als wäre er ursprünglich dieser Wert. Der vorherige Wert der `req.method` wird in `req.originalMethod` gespeichert. @@ -91,7 +91,7 @@ app.use(methodOverride('X-HTTP-Method-Override')); Beispielaufruf mit Überschreibung mit `XMLHttpRequest`: -{/* eslint-env Browser */} +{/* eslint-env browser */} ```js const xhr = new XMLHttpRequest(); diff --git a/src/content/pages/de/resources/middleware/morgan.mdx b/src/content/pages/de/resources/middleware/morgan.mdx index 976ed22d0d..8d4fc04a0e 100644 --- a/src/content/pages/de/resources/middleware/morgan.mdx +++ b/src/content/pages/de/resources/middleware/morgan.mdx @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa @@ -35,13 +35,13 @@ Dies ist ein [Node.js](https://nodejs.org/en/) Modul über die ## API -{/* eslint-deaktivieren Sie keine unbenutzten vars */} +{/* eslint-disable no-unused-vars */} ```js var morgan = require('morgan'); ``` -### morgan(Format, Optionen) +### morgan(format, options) Erstelle eine neue morgan logger Middleware-Funktion mit dem angegebenen `format` und `options`. Das `format` Argument kann ein String eines vordefinierten Namens sein (siehe unten für die Namen) @@ -54,7 +54,7 @@ oder `undefined` / `null` sein wird, um die Protokollierung zu überspringen. #### Eine vordefinierte Format-Zeichenkette verwenden -{/* eslint-Deaktiviere keinen Untoten */} +{/* eslint-disable no-undef */} ```js morgan('tiny'); @@ -62,7 +62,7 @@ morgan('tiny'); #### Format-Zeichenkette von vordefinierten Tokens verwenden -{/* eslint-Deaktiviere keinen Untoten */} +{/* eslint-disable no-undef */} ```js morgan(':method :url :status :res[content-length] - :response-time ms'); @@ -70,7 +70,7 @@ morgan(':method :url :status :res[content-length] - :response-time ms'); #### Verwende eine benutzerdefinierte Formatfunktion -{/* eslint-Deaktiviere keinen Untoten */} +{/* eslint-disable no-undef */} ```js morgan(function (tokens, req, res) { @@ -88,18 +88,18 @@ morgan(function (tokens, req, res) { Morgan akzeptiert diese Eigenschaften im Optionsobjekt. -##### sofort +##### immediate Schreiben Sie die Logzeile auf Anfrage statt auf Antwort. Dies bedeutet, dass Anfragen protokolliert werden, auch wenn der Server abstürzt, _aber Daten aus der Antwort (wie der Antwortcode usw.) kann nicht protokolliert werden_. -##### überspringen +##### skip Funktion, um festzustellen, ob die Protokollierung übersprungen wird, wird standardmäßig `false` verwendet. Diese Funktion wird als `skip(req, res)` aufgerufen. -{/* eslint-Deaktiviere keinen Untoten */} +{/* eslint-disable no-undef */} ```js // EXAMPLE: only log error responses @@ -110,7 +110,7 @@ morgan('combined', { }); ``` -##### streamen +##### stream Ausgabe-Stream zum Schreiben von Logzeilen, standardmäßig `process.stdout`. @@ -118,7 +118,7 @@ Ausgabe-Stream zum Schreiben von Logzeilen, standardmäßig `process.stdout`. Es werden verschiedene vordefinierte Formate bereitgestellt: -##### kombiniert +##### combined Standard Apache kombinierte Logausgabe. @@ -128,7 +128,7 @@ Standard Apache kombinierte Logausgabe. ::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1" ``` -##### häufig +##### common Standard Apache gemeinsame Protokollausgabe. @@ -138,7 +138,7 @@ Standard Apache gemeinsame Protokollausgabe. ::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2 ``` -##### dew +##### dev Existiert die Ausgabe, die nach Antwortstatus für die Entwicklungsanwendung gefärbt wird. Der `:status` Token wird grün für Erfolgscodes eingefärbt, rot für Server-Fehlercodes, @@ -151,7 +151,7 @@ für Informationscodes. GET /dev 200 0.224 ms - 2 ``` -##### kurz +##### short Kürzer als Standardwert, auch mit Antwortzeit. @@ -161,7 +161,7 @@ Kürzer als Standardwert, auch mit Antwortzeit. ::1 - GET /short HTTP/1.1 200 2 - 0.283 ms ``` -##### winzig +##### tiny Die minimale Ausgabe. @@ -179,7 +179,7 @@ Um ein Token zu definieren, rufen Sie einfach `morgan.token()` mit dem Namen und Diese Callback-Funktion wird voraussichtlich einen String-Wert zurückgeben. Der zurückgegebene Wert ist dann verfügbar als ":type" in diesem Fall: -{/* eslint-Deaktiviere keinen Untoten */} +{/* eslint-disable no-undef */} ```js morgan.token('type', function (req, res) { @@ -200,11 +200,11 @@ Das aktuelle Datum und die Uhrzeit in UTC. Die verfügbaren Formate sind: - `clf` für das gemeinsame Protokollformat (`"10/Oct/2000:13:55:36 +0000"`) - `iso` für das gemeinsame ISO 8601 Datumsformat (`2000-10-10T13:55:36.000Z`) -- `web` für das übliche RFC 1123 Datumsformat (`Die, 10 Okt 2000 13:55:36 GMT`) +- `web` für das übliche RFC 1123 Datumsformat (`Tue, 10 Oct 2000 13:55:36 GMT`) Wenn kein Format angegeben ist, dann ist der Standard `web`. -##### :http-Version +##### :http-version Die HTTP-Version der Anfrage. @@ -224,7 +224,7 @@ Der Referrer-Header der Anfrage. Dies wird den Standard-falsch geschriebenen Ref Die entfernte Adresse der Anfrage. Dies wird `req.ip` verwenden, andernfalls der Standardwert `req.connection.remoteAddress` (Socket-Adresse). -##### :Remote-Benutzer +##### :remote-user Der Benutzer hat sich als Teil des Basic auth für die Anfrage authentifiziert. @@ -238,7 +238,7 @@ Wert im Log als `"-"` angezeigt. Der angegebene `header` der Antwort. Wenn der Header nicht vorhanden ist, wird der Wert im Log als `"-"` angezeigt. -##### :Antwortzeit[digits] +##### :response-time[digits] Die Zeit zwischen der Anfrage, die in `morgan` eintrifft, und der Antwort- -Header in Millisekunden. @@ -254,7 +254,7 @@ Wenn der Anfrage/Antwortzyklus abgeschlossen ist, bevor eine Antwort an den Client gesendet wurde (zum Beispiel der TCP-Socket wurde vorzeitig von einem Client geschlossen, der die Anfrage abbrecht), dann wird der Status leer sein (wird als `"-"` im Log angezeigt). -##### :Gesamtzeit[digits] +##### :total-time[digits] Die Zeit zwischen der Anfrage, die in `morgan` eintrifft, und wenn die Antwort beendet ist, wird in Millisekunden auf die Verbindung geschrieben. @@ -266,7 +266,7 @@ enthalten ist für die Zahl, Standardwert ist `3`, was die Genauigkeit der Mikro Die URL der Anfrage. Dies wird `req.originalUrl` verwenden, wenn vorhanden, andernfalls `req.url`. -##### :user-Agent +##### :user-agent Der Inhalt des User-Agent-Headers der Anfrage. @@ -278,7 +278,7 @@ Token sind Referenzen von `:token-name`. Wenn Tokens Argumente akzeptieren, kön mit `[]` übergeben werden, zum Beispiel: `:token-name[pretty]` würde den String `'pretty'` als Argument an den Token `token-name` übergeben. -Die Funktion kam von `morgan. ompile` verwendet drei Argumente `tokens`, `req` und +Die Funktion kam von `morgan.compile` verwendet drei Argumente `tokens`, `req` und `res`, wobei `tokens` Objekt mit allen definierten Tokens ist, `req` ist die HTTP-Anfrage und `res` ist die HTTP-Antwort. Die Funktion gibt einen String zurück, der die Log-Zeile, oder `undefined` / `null` sein wird, um die Protokollierung zu überspringen. @@ -288,7 +288,7 @@ erweiterte Anwendungen ist diese Kompilierungsfunktion direkt verfügbar. ## Beispiele -### ausdrucken/verbinden +### express/connect Beispiel-App, die alle Anfragen im Apache kombinierten Format in STDOUT protokolliert diff --git a/src/content/pages/de/resources/middleware/multer.mdx b/src/content/pages/de/resources/middleware/multer.mdx index ff04f97fbb..b720ad928f 100644 --- a/src/content/pages/de/resources/middleware/multer.mdx +++ b/src/content/pages/de/resources/middleware/multer.mdx @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa @@ -22,18 +22,18 @@ oben auf [busboy](https://github.com/mscdex/busboy) geschrieben, um maximale Eff Diese README ist auch in anderen Sprachen verfügbar: -| | | -| -------------------------------------------------------------------------------------------- | ------------------ | -| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabisch | -| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinesisch | -| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | Französisch | -| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Koreanisch | -| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portugiesisch (BR) | -| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russisch | -| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanisch | -| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek | -| [Ansicht\ \ t Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese | -| [Türkçe](https://github.com/expressjs/multer/blob/main/doc/README-tr.md) | Türkisch | +| | | +| ------------------------------------------------------------------------------ | ------------------ | +| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabisch | +| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinesisch | +| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | Französisch | +| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Koreanisch | +| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portugiesisch (BR) | +| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russisch | +| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanisch | +| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek | +| [Việt Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese | +| [Türkçe](https://github.com/expressjs/multer/blob/main/doc/README-tr.md) | Türkisch | ## Installation @@ -138,15 +138,15 @@ Jede Datei enthält folgende Informationen: | Schlüssel | Beschreibung | Notiz | | -------------- | ---------------------------------------------- | --------------- | -| Feldname | Feldname im Formular angegeben | | +| `fieldname` | Feldname im Formular angegeben | | | `originalname` | Name der Datei auf dem Computer des Benutzers | | -| `codieren` | Kodierungstyp der Datei | | -| "mimetype" | Mime-Typ der Datei | | +| `encoding` | Kodierungstyp der Datei | | +| `mimetype` | Mime-Typ der Datei | | | `size` | Größe der Datei in Bytes | | -| "Ziel" | Der Ordner, in dem die Datei gespeichert wurde | `DiskStorage` | -| "Dateiname" | Der Name der Datei innerhalb des `destination` | `DiskStorage` | +| `destination` | Der Ordner, in dem die Datei gespeichert wurde | `DiskStorage` | +| `filename` | Der Name der Datei innerhalb des `destination` | `DiskStorage` | | `path` | Der vollständige Pfad zur hochgeladenen Datei | `DiskStorage` | -| 'buffer' | Ein `Buffer` der gesamten Datei | `MemoryStorage` | +| `buffer` | Ein `Buffer` der gesamten Datei | `MemoryStorage` | ### `multer(opts)` @@ -159,13 +159,13 @@ Umbenennungsfunktion kann an Ihre Bedürfnisse angepasst werden. Die folgenden Optionen können an Multer übergeben werden. -| Schlüssel | Beschreibung | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| "dest" oder "Speicher" | Wo die Dateien gespeichert werden sollen | -| "fileFilter" | Funktion, um zu kontrollieren, welche Dateien akzeptiert werden | -| `Limits` | Grenzen der hochgeladenen Daten | -| `preservePath` | Behalte den vollen Pfad der Dateien statt nur des Basisnamens | -| `defParamCharset` | Standardzeichensatz für Werte von Bauteilheader-Parametern (z.B. Dateiname), die keine erweiterten Parameter sind (welche einen expliziten Zeichensatz enthalten). Standard: \`'latin1' | +| Schlüssel | Beschreibung | +| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `dest` oder `storage` | Wo die Dateien gespeichert werden sollen | +| `fileFilter` | Funktion, um zu kontrollieren, welche Dateien akzeptiert werden | +| `limits` | Grenzen der hochgeladenen Daten | +| `preservePath` | Behalte den vollen Pfad der Dateien statt nur des Basisnamens | +| `defParamCharset` | Standardzeichensatz für Werte von Bauteilheader-Parametern (z.B. Dateiname), die keine erweiterten Parameter sind (welche einen expliziten Zeichensatz enthalten). Standard: `'latin1'` | In einer durchschnittlichen Web-App könnte nur `dest` erforderlich sein, und konfiguriert werden, wie in das folgende Beispiel. @@ -178,14 +178,14 @@ Wenn du mehr Kontrolle über deine Uploads haben möchtest, möchtest du die Opt anstelle von `dest` verwenden. Multerschiffe mit Speichermotoren `DiskStorage` und `MemoryStorage`; Weitere Motoren sind von Dritten erhältlich. -#### `.single(Feldname)` +#### `.single(fieldname)` -Akzeptieren Sie eine einzelne Datei mit dem Namen `Feldname`. Die einzelne Datei wird +Akzeptieren Sie eine einzelne Datei mit dem Namen `fieldname`. Die einzelne Datei wird in `req.file` gespeichert. -#### `.array(Feldname[, maxCount])` +#### `.array(fieldname[, maxCount])` -Akzeptieren Sie ein Array von Dateien, alle mit dem Namen `Feldname`. Optionaler Fehler wenn +Akzeptieren Sie ein Array von Dateien, alle mit dem Namen `fieldname`. Optionaler Fehler wenn mehr als `maxCount`-Dateien hochgeladen werden. Das Array der Dateien wird in `req.files` gespeichert. @@ -219,7 +219,7 @@ Fügen Sie Multer nie als globale Middleware hinzu, da ein böswilliger Benutzer Dateien zu einer Route hochladen konnte, die Sie nicht erwartet haben. Verwenden Sie diese Funktion nur auf Routen , wo Sie die hochgeladenen Dateien behandeln. -### "Speicher" +### `storage` #### `DiskStorage` @@ -266,7 +266,7 @@ Reihenfolge ab, dass der Client Felder und Dateien an den Server überträgt. Um die im Callback verwendete Aufrufkonvention zu verstehen (muss Null als erster Parameter übergeben werden), lesen Sie bitte -[Node. s Fehlerbehandlung](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors) +[Node.js Fehlerbehandlung](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors) #### `MemoryStorage` @@ -285,7 +285,7 @@ Wenn Sie Speicher verwenden, enthält die Datei-Info ein Feld mit dem Namen -Zahlen sehr schnell kann dazu führen, dass Ihre Anwendung bei Verwendung des Arbeitsspeichers nicht mehr genügend Speicher hat. -### `Limits` +### `limits` Ein Objekt, das die Größengrenzen der folgenden optionalen Eigenschaften angibt. Multer übergibt dieses Objekt direkt an den Busboy und die Details der Eigenschaften finden Sie auf [Busboys Seite](https://github.com/mscdex/busboy#busboy-methods). @@ -293,18 +293,18 @@ Die folgenden Ganzzahlwerte sind verfügbar: | Schlüssel | Beschreibung | Standard | | ------------------- | ---------------------------------------------------------------------------------------------------- | ------------- | -| "fieldNameSize" | Max. Feldnamensgröße | 100 Bytes | -| "fieldGröße" | Maximale Feldwertgröße (in Bytes) | 1MB | -| `Felder` | Maximale Anzahl von Nicht-Dateifeldern | Unendlichkeit | -| Dateigröße | Für mehrteilige Formulare ist die maximale Dateigröße (in Bytes) | Unendlichkeit | -| `Dateien` | Für mehrteilige Formulare ist die maximale Anzahl von Dateifeldern | Unendlichkeit | -| "Teile" | Für mehrteilige Formulare ist die maximale Anzahl von Teilen (Felder + Dateien) | Unendlichkeit | -| "headerPairs" | Bei mehrteiligen Formularen ist die maximale Anzahl der Kopfzeilen-Schlüssel=>Werte-Paare zum Parsen | 2000 | +| `fieldNameSize` | Max. Feldnamensgröße | 100 Bytes | +| `fieldSize` | Maximale Feldwertgröße (in Bytes) | 1MB | +| `fields` | Maximale Anzahl von Nicht-Dateifeldern | Unendlichkeit | +| `fileSize` | Für mehrteilige Formulare ist die maximale Dateigröße (in Bytes) | Unendlichkeit | +| `files` | Für mehrteilige Formulare ist die maximale Anzahl von Dateifeldern | Unendlichkeit | +| `parts` | Für mehrteilige Formulare ist die maximale Anzahl von Teilen (Felder + Dateien) | Unendlichkeit | +| `headerPairs` | Bei mehrteiligen Formularen ist die maximale Anzahl der Kopfzeilen-Schlüssel=>Werte-Paare zum Parsen | 2000 | | `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Unendlichkeit | Die Angabe der Grenzwerte kann dazu beitragen, Ihre Website vor Denial of Service (DoS) Attacken zu schützen. -### "fileFilter" +### `fileFilter` Setze dies auf eine Funktion um zu kontrollieren, welche Dateien hochgeladen werden sollen und welche übersprungen werden soll. Die Funktion sollte so aussehen: @@ -340,7 +340,7 @@ Wenn ein Fehler auftritt, wird Multer den Fehler an Express übertragen. Du kann eine schöne Fehlerseite anzeigen, indem du [den Standard-Express-Weg](/guide/error-handling). Wenn Sie Fehler speziell von Multer auffangen möchten, können Sie die -Middleware-Funktion selbst aufrufen. Außerdem, wenn du nur [die Multer-Fehler] fangen möchtest (https://github.com/expressjs/multer/blob/main/lib/multer-error.js), du kannst die `MulterError` Klasse verwenden, die an das `multer` Objekt selbst angeschlossen ist (e. . `err instance`multer.MulterError\`). +Middleware-Funktion selbst aufrufen. Außerdem, wenn du nur [die Multer-Fehler] fangen möchtest (https://github.com/expressjs/multer/blob/main/lib/multer-error.js), du kannst die `MulterError` Klasse verwenden, die an das `multer` Objekt selbst angeschlossen ist (z. B. `err instanceof multer.MulterError`). ```javascript const multer = require('multer'); @@ -368,5 +368,5 @@ Informationen zum Aufbau Ihrer eigenen Speicher-Engine finden Sie unter [Multer [MIT](https://github.com/expressjs/multer/blob/HEAD/LICENSE) [npm-url]: https://npmjs.org/package/multer -[ossf-Scorecard-Abzeichen]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[ossf-Punkte-Visualisierer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer +[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer diff --git a/src/content/pages/de/resources/middleware/response-time.mdx b/src/content/pages/de/resources/middleware/response-time.mdx index 06d16f4f7e..a02575a1ef 100644 --- a/src/content/pages/de/resources/middleware/response-time.mdx +++ b/src/content/pages/de/resources/middleware/response-time.mdx @@ -1,5 +1,5 @@ --- -title: antwortzeit-Middleware +title: response-time Middleware description: Antwortzeit für Node.js Server --- @@ -9,8 +9,8 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa Antwortzeit für Node.js Server. @@ -38,7 +38,7 @@ Dies ist ein [Node.js](https://nodejs.org/en/) Modul über die ## API -{/* eslint-deaktivieren Sie keine unbenutzten vars */} +{/* eslint-disable no-unused-vars */} ```js var responseTime = require('response-time'); @@ -60,7 +60,7 @@ contain any of the following keys: Die festgelegte Anzahl an Ziffern, die in der Ausgabe enthalten sein sollen, die immer in Millisekunden ist, Standardwert ist `3` (z.B.: `2.300ms`). -##### kopf +##### header Der Name des zu setzenden Headers, standardmäßig `X-Response-Time`. @@ -77,7 +77,7 @@ als `fn(req, res, time)` aufgerufen, wobei `time` eine Zahl in Millisekunden ist ## Beispiele -### ausdrucken/verbinden +### express/connect ```js var express = require('express'); @@ -144,5 +144,5 @@ app.get('/', function (req, res) { [MIT](https://github.com/expressjs/response-time/blob/HEAD/LICENSE) -[npm-url]: https://npmjs.org/package/Antwortzeit -[node-url]: https://nodejs.org/de/download +[npm-url]: https://npmjs.org/package/response-time +[node-url]: https://nodejs.org/en/download diff --git a/src/content/pages/de/resources/middleware/serve-favicon.mdx b/src/content/pages/de/resources/middleware/serve-favicon.mdx index 5ba6e7e162..e1c94a8dd3 100644 --- a/src/content/pages/de/resources/middleware/serve-favicon.mdx +++ b/src/content/pages/de/resources/middleware/serve-favicon.mdx @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa @@ -21,14 +21,14 @@ a site. Für ein Beispiel und weitere Informationen besuchen Sie bitte Warum dieses Modul verwenden? -- User Agents fordern `favicon. co` häufig und unterschiedslos, damit Sie +- User Agents fordern `favicon.ico` häufig und unterschiedslos, damit Sie diese Anfragen von Ihren Logs ausschließen möchten, indem Sie diese Middleware vor Ihrer Middleware verwenden. - Dieses Modul speichert das Symbol im Speicher, um die Leistung zu verbessern, indem Sie den Zugriff auf die Festplatte überspringen. - Dieses Modul bietet einen `ETag` basierend auf dem Inhalt des Icons, eher als Dateisystemeigenschaften. -- Dieses Modul wird mit dem kompatibelsten "Content-Type" ausgeliefert. +- Dieses Modul wird mit dem kompatibelsten `Content-Type` ausgeliefert. **Notiz** Dieses Modul dient ausschliesslich für den "Standard-, implizite Favicon", , der `GET /favicon.ico` ist. For additional vendor-specific icons that require @@ -53,7 +53,7 @@ Dies ist ein [Node.js](https://nodejs.org/en/) Modul über die ## API -### favicon(Pfad, Optionen) +### favicon(path, options) Erstelle neue Middleware, um ein Favicon aus dem angegebenen `path` zu einer Favicon-Datei zu liefern. `path` kann auch ein `Buffer` des zu dienenden Icons sein. @@ -70,11 +70,10 @@ module. ## Beispiele -Normalerweise kommt diese Middleware sehr früh in Ihrem Stapel (vielleicht sogar zuerst) -, um keine andere Middleware zu verarbeiten, wenn wir bereits wissen, dass die Anfrage für -`/favicon ist. co`. +Normalerweise kommt diese Middleware sehr früh in Ihrem Stapel (vielleicht sogar zuerst), um keine andere Middleware zu verarbeiten, wenn wir bereits wissen, dass die Anfrage für +`/favicon.ico`. -### ausdrücken +### express ```javascript var express = require('express'); @@ -89,7 +88,7 @@ app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.listen(3000); ``` -### verbinden +### connect ```javascript var connect = require('connect'); @@ -139,5 +138,5 @@ server.listen(3000); [downloads-url]: https://npmjs.org/package/serve-favicon [npm-url]: https://npmjs.org/package/serve-favicon -[ossf-Scorecard-Abzeichen]: https://api.scorecard.dev/projects/github.com/expressjs/serve-favicon/badge -[ossf-Punkte-Visualisierer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/serve-favicon +[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/serve-favicon/badge +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/serve-favicon diff --git a/src/content/pages/de/resources/middleware/serve-index.mdx b/src/content/pages/de/resources/middleware/serve-index.mdx index 1193481d7b..691c870de6 100644 --- a/src/content/pages/de/resources/middleware/serve-index.mdx +++ b/src/content/pages/de/resources/middleware/serve-index.mdx @@ -1,5 +1,5 @@ --- -title: dienst-Index Middleware +title: serve-index Middleware description: Serve-Verzeichnislisten --- @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa @@ -37,23 +37,23 @@ Dies ist ein [Node.js](https://nodejs.org/en/) Modul über die var serveIndex = require('serve-index'); ``` -### serveIndex(Pfad, Optionen) +### serveIndex(path, options) Gibt Middlware zurück, die einen Index des Verzeichnisses im angegebenen `path` enthält. -Der `path` basiert auf dem `req.url` Wert, also wird eine `req.url` von `'/some/dir` +Der `path` basiert auf dem `req.url` Wert, also wird eine `req.url` von `'/some/dir'` mit einem `path` von `'public'` auf `'public/some/dir'` schauen. Wenn du -so etwas wie `express verwendest, kannst du die URL "base" mit `app.use\` ändern (siehe +so etwas wie `express` verwendest, kannst du die URL "base" mit `app.use` ändern (siehe das Expressbeispiel). #### Optionen Serve-Index akzeptiert diese Eigenschaften im Options-Objekt. -##### filtern +##### filter Diese Filterfunktion auf Dateien anwenden. Standard ist `false`. Die `filter` Funktion -wird für jede Datei aufgerufen, mit der Signatur `filter(Dateiname, Index, Dateien, dir)` +wird für jede Datei aufgerufen, mit der Signatur `filter(filename, index, files, dir)` wobei `filename` der Name der Datei ist `index` ist der Array-Index, `files` ist das Array der Dateien und `dir` ist der absolute Pfad, den die Datei befindet (und somit das Verzeichnis, für das das Angebot bestimmt ist). @@ -62,7 +62,7 @@ das Verzeichnis, für das das Angebot bestimmt ist). Versteckte (Punkte) Dateien anzeigen. Standard ist `false`. -##### symbole +##### icons Symbole anzeigen. Standard ist `false`. @@ -70,7 +70,7 @@ Symbole anzeigen. Standard ist `false`. Optionaler Pfad zu einem CSS-Stylesheet. Standardmäßig ein eingebautes Stylesheet. -##### vorlage +##### template Optionaler Pfad zu einer HTML-Vorlage oder einer Funktion, die einen HTML- -String darstellen wird. Standardmäßig wird eine eingebaute Vorlage verwendet. @@ -97,7 +97,7 @@ angegebenen Gebietsschema: - `style` ist das Standardstylesheet oder der Inhalt der `stylesheet` Option. - `viewName` ist der Ansichtsname, der von der `view` Option angegeben wird. -##### anschauen +##### view Anzeigemodus. `tiles` und `details` sind verfügbar. Standard ist `tiles`. diff --git a/src/content/pages/de/resources/middleware/serve-static.mdx b/src/content/pages/de/resources/middleware/serve-static.mdx index d2db309967..2a6e4dae59 100644 --- a/src/content/pages/de/resources/middleware/serve-static.mdx +++ b/src/content/pages/de/resources/middleware/serve-static.mdx @@ -1,5 +1,5 @@ --- -title: statische Middleware +title: serve-static Middleware description: Statische Dateien Servieren --- @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa @@ -35,7 +35,7 @@ Dies ist ein [Node.js](https://nodejs.org/en/) Modul über die const serveStatic = require('serve-static'); ``` -### serveStatic(root, Optionen) +### serveStatic(root, options) Erstellen Sie eine neue Middleware-Funktion, um Dateien innerhalb eines angegebenen Wurzel- -Verzeichnisses zu bedienen. Die zu bedienende Datei wird durch die Kombination von `req.url` @@ -45,7 +45,7 @@ zur nächsten Middleware zu bewegen, was Stapeln und Fallbacks erlaubt. #### Optionen -##### akzeptiere Wertebereiche +##### acceptRanges Aktivieren oder deaktivieren Sie die Annahme von Fernanforderungen. Standardmäßig ist dies wahr. Deaktivieren wird `Accept-Ranges` nicht senden und den Inhalt @@ -62,20 +62,20 @@ Legen Sie fest, wie "dotfiles" beim Auftreten behandelt werden. Eine Dotdatei is oder ein Verzeichnis, das mit einem Punkt beginnt ("."). Beachten Sie, dass diese Überprüfung auf durchgeführt wird, ohne zu überprüfen, ob der Pfad tatsächlich auf der Platte vorhanden ist. Wenn `root` angegeben ist, werden nur die Punkte oberhalb des Roots -aktiviert (i. . Das Root selbst kann innerhalb einer dotfile liegen, wenn -auf "deny" gesetzt wird. +aktiviert (d. i. Das Root selbst kann innerhalb einer dotfile liegen, wenn +auf "deny" gesetzt wird). -- `erlaub'` Keine spezielle Behandlung für dotfiles. +- `'allow'` Keine spezielle Behandlung für dotfiles. - `'deny'` leugne eine Anfrage für eine dotfile und 403/`next()`. - `'ignore'` Pretend as the dotfile does not exist and 404/`next()`. -Der Standardwert ist 'ignore'. +Der Standardwert ist `'ignore'`. ##### etag Aktiviere oder deaktiviere Etagenerzeugung, Standardwert ist 'true'. -##### erweiterungen +##### extensions Fallbacks für Dateierweiterung festlegen. Wenn gesetzt, wenn eine Datei nicht gefunden wird, werden die angegebenen -Erweiterungen zum Dateinamen hinzugefügt und gesucht. Die Erste, die @@ -83,7 +83,7 @@ existiert, wird bedient. Example: `['html', 'htm']`. Der Standardwert ist `false`. -##### durchfallen +##### fallthrough Legen Sie die Middleware so fest, dass Client-Fehler nur als unbehandelte -Anfragen durchlaufen, sonst leiten Sie einen Client-Fehler weiter. Der Unterschied ist, dass Client- @@ -102,7 +102,7 @@ alle Methoden antworten. Der Standardwert ist `true`. -##### unveränderbar +##### immutable Aktivieren oder deaktivieren Sie die `immutable` Direktive in der `Cache-Control` Antwort -Kopfzeile, standardmäßig `false`. Wenn `true` gesetzt ist, sollte die `maxAge` Option @@ -110,13 +110,13 @@ ebenfalls angegeben werden, um das Caching zu aktivieren. The `immutable` direct supported clients from making conditional requests during the life of the `maxAge` option to check if the file has changed. -##### indexieren +##### index Standardmäßig sendet dieses Modul "index.html" Dateien als Antwort auf eine Anfrage in einem Verzeichnis. Um diese Einstellung zu deaktivieren `false` oder um einen neuen Index anzuliefern, übergeben Sie einen String oder ein Array in bevorzugter Reihenfolge. -##### zuletzt geändert +##### lastModified Aktiviere oder deaktiviere `Last-Modified` Header. Standardmäßig ist 'true'. Verwendet den zuletzt geänderten Wert der Datei . @@ -127,7 +127,7 @@ Geben Sie ein Max-Alter in Millisekunden für http Caching an, standardmäßig 0 can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme) module. -##### umleiten +##### redirect Umleiten zu "/" am Ende, wenn der Pfadname ein dir. Standard ist `true`. @@ -138,8 +138,8 @@ occur synchronously. Die Funktion wird als `fn(res, path, stat)` aufgerufen, wob die Argumente sind: - `res` das Antwortobjekt -- "path" der Dateipfad, der gesendet wird -- "stat" das stat-Objekt der zu sendenden Datei +- `path` der Dateipfad, der gesendet wird +- `stat` das stat-Objekt der zu sendenden Datei ## Beispiele @@ -258,5 +258,5 @@ function setCustomCacheControl(res, file) { [MIT](https://github.com/expressjs/serve-static/blob/HEAD/LICENSE) -[node-url]: https://nodejs.org/de/download/ +[node-url]: https://nodejs.org/en/download/ [npm-url]: https://npmjs.org/package/serve-static diff --git a/src/content/pages/de/resources/middleware/session.mdx b/src/content/pages/de/resources/middleware/session.mdx index 057fb16e79..801ea9fbba 100644 --- a/src/content/pages/de/resources/middleware/session.mdx +++ b/src/content/pages/de/resources/middleware/session.mdx @@ -1,5 +1,5 @@ --- -title: session-Middleware +title: session Middleware description: Einfache Sitzungs-Middleware für Express --- @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa @@ -35,7 +35,7 @@ Dies ist ein [Node.js](https://nodejs.org/en/) Modul über die var session = require('express-session'); ``` -### session(Optionen) +### session(options) Erstellen Sie eine Session Middleware mit den angegebenen `Optionen`. @@ -58,7 +58,7 @@ Eine Liste der Geschäfte finden Sie unter [kompatible Session-Shopes](#compatib `express-session` akzeptiert diese Eigenschaften im Optionsobjekt. -##### kochen +##### cookie Einstellungsobjekt für das Session-ID-Cookie. Der Standardwert ist `{ path: '/', httpOnly: true, secure: false, maxAge: null }`. @@ -125,7 +125,7 @@ kein Maximalalter gesetzt. **Notiz** Wenn sowohl `expires` als auch `maxAge` in den Optionen gesetzt werden, dann ist das letzte im Objekt was verwendet wird. -##### cookie.partitioniert +##### cookie.partitioned Gibt den `boolean` Wert für das [`Partitioned` `Set-Cookie`](https://github.com/expressjs/session/blob/HEAD/rfc-cutler-httpbis-partitioned-cookies) Attribut an. Wenn Wahrheit, ist das `Partitioned` Attribut gesetzt, andernfalls nicht. @@ -138,10 +138,10 @@ Weitere Informationen finden Sie in [dem Vorschlag](https://github.com/privacycg ##### cookie.path -Gibt den Wert für `Path` `Set-Cookie` an. Standardmäßig wird dies auf \`'/' gesetzt, welcher +Gibt den Wert für `Path` `Set-Cookie` an. Standardmäßig wird dies auf `'/'` gesetzt, welcher der Wurzelpfad der Domain ist. -##### cookie.priorität +##### cookie.priority Legt den `string` als Wert für das [`Priority` `Set-Cookie` Attribut][rfc-west-cookie-priority-00-4.1] fest. @@ -285,7 +285,7 @@ Der Standardwert ist nicht definiert. als sicher angesehen, wenn es eine direkte TLS/SSL-Verbindung gibt. - `undefined` verwendet die "trust proxy"-Einstellung von express -##### neuladen +##### resave Erzwingt die Sitzung, wieder im Session-Store zu speichern, selbst wenn die Sitzung während der Anfrage nie geändert wurde. Abhängig von Ihrem Shop könnte dies @@ -304,7 +304,7 @@ können Sie sicher `resave: false` setzen. Wenn die `touch` Methode nicht implementiert wird und Ihr Shop ein Ablaufdatum für gespeicherte Sitzungen festlegt, dann müssen Sie wahrscheinlich `resave: true`. -##### rollen +##### rolling Erzwingen Sie das Session-Identifikator-Cookie bei jeder Antwort zu setzen. Die Ablaufzeit wird auf das Original [`maxAge`](#cookiemaxage), zurückgesetzt und das Ablaufdatum @@ -325,7 +325,7 @@ auf `false` gesetzt, das Cookie wird nicht auf eine Antwort mit einer nicht init Sitzung gesetzt. Diese Option ändert nur das Verhalten, wenn eine bestehende Sitzung für die Anfrage geladen wurde. -##### saveUninitialisiert +##### saveUninitialized Zwingt eine Sitzung, die "uninitialisiert" ist, in den Store gespeichert werden. Eine Sitzung ist uninitialisiert, wenn sie neu ist, aber nicht geändert wurde. Das Auswählen von `false` ist nützlich für @@ -343,7 +343,7 @@ fügt ein leeres Passport-Objekt zur Sitzung hinzu, nachdem ein Benutzer authentifiziert ist , was als Änderung der Sitzung behandelt wird, wodurch gespeichert wird. _Dies wurde in PassportJS 0.3.0_ behoben -##### geheim +##### secret **Benötigte Option** @@ -371,16 +371,16 @@ Elemente. **Notiz** HMAC-256 wird benutzt um die Session-ID zu signieren. Aus diesem Grund sollte das Geheimnis mindestens 32 Bytes Entropie enthalten. -##### speichern +##### store Die Session-Shop-Instanz ist standardmäßig eine neue `MemoryStore`-Instanz. -##### entfernt +##### unset Kontrollieren Sie das Ergebnis der Einstellung `req.session` (durch `delete`, Einstellung auf `null`, etc.). -Der Standardwert ist \`'keep'. +Der Standardwert ist `'keep'`. - `'destroy'` Die Sitzung wird zerstört (gelöscht), wenn die Antwort endet. - `'keep'` Die Sitzung im Shop wird beibehalten, aber Änderungen während @@ -423,7 +423,7 @@ req.session.regenerate(function (err) { }); ``` -#### Session.destroy(Rückruf) +#### Session.destroy(callback) Zerstört die Sitzung und wird die `req.session` Eigenschaft entfernen. Sobald der `Callback` abgeschlossen ist, wird der `Callback` aufgerufen. @@ -434,7 +434,7 @@ req.session.destroy(function (err) { }); ``` -#### Session.reload(Callback) +#### Session.reload(callback) Lädt die Sitzungsdaten aus dem Shop neu und füllt das `req.session` Objekt neu. Sobald der `Callback` abgeschlossen ist, wird der `Callback` aufgerufen. @@ -445,7 +445,7 @@ req.session.reload(function (err) { }); ``` -#### Session.save(Callback) +#### Session.save(callback) Speichere die Session zurück im Shop, Ersetzen der Inhalte im Shop durch den Inhalt im Speicher (obwohl ein Shop etwas anderes tun kann - konsultieren Sie die @@ -596,7 +596,7 @@ könnte den Leerlauf-Timer zurücksetzen. Die folgenden Module implementieren einen Session-Shop, der mit diesem -Modul kompatibel ist. Bitte machen Sie einen PR um zusätzliche Module hinzuzufügen :) -[![★][aerospike-session-store-image] [aerospike-session-store-image] Aerospike-session-store][aerospike-session-store-url] Ein Session-Shop mit [Aerospike](http://www.aerospike.com/). +[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] Ein Session-Shop mit [Aerospike](http://www.aerospike.com/). [aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store @@ -1001,7 +1001,7 @@ Verwenden Sie unter Windows den entsprechenden Befehl; [MIT](https://github.com/expressjs/session/blob/HEAD/LICENSE) [rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7 -[rfc-cutler-httpbis-partitionierte Cookies]: +[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/ [rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1 -[node-url]: https://nodejs.org/de/download +[node-url]: https://nodejs.org/en/download [npm-url]: https://npmjs.org/package/express-session diff --git a/src/content/pages/de/resources/middleware/timeout.mdx b/src/content/pages/de/resources/middleware/timeout.mdx index f008abb3cc..1244f12b4b 100644 --- a/src/content/pages/de/resources/middleware/timeout.mdx +++ b/src/content/pages/de/resources/middleware/timeout.mdx @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa @@ -57,7 +57,7 @@ akzeptiert wird. Beim Timeout wird `req` \`"timeout" emittieren. Die `timeout` Funktion benötigt ein optionales `options` Objekt, das eines der folgenden Schlüssel enthalten kann: -##### antworten +##### respond Legt fest, ob dieses Modul in Form der Weiterleitung eines Fehlers "reagiert" wird. Falls `true`, wird der Timeout-Fehler an `next()` übergeben, so dass du das Antwortverhalten @@ -107,7 +107,7 @@ function haltOnTimedout(req, res, next) { app.listen(3000); ``` -### explizit 3.x +### express 3.x ```javascript var express = require('express'); @@ -139,7 +139,7 @@ function savePost(post, cb) { app.listen(3000); ``` -### verbinden +### connect ```javascript var bodyParser = require('body-parser'); diff --git a/src/content/pages/de/resources/middleware/vhost.mdx b/src/content/pages/de/resources/middleware/vhost.mdx index 695cc24ef2..2f7b02f2e7 100644 --- a/src/content/pages/de/resources/middleware/vhost.mdx +++ b/src/content/pages/de/resources/middleware/vhost.mdx @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa @@ -31,7 +31,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa var vhost = require('vhost'); ``` -### vhost(Hostname, Handle) +### vhost(hostname, handle) Erstelle eine neue Middleware-Funktion, um die Anfrage an `handle` zu übergeben, wenn der eingehende Host für die Anfrage mit `hostname` übereinstimmt. Die Funktion wird wie eine Standard-Middleware als @@ -66,7 +66,7 @@ app.use( ## Beispiele -### mit Verbindung für statische Servierung verwenden +### mit connect für statische Servierung verwenden ```js var connect = require('connect'); @@ -96,7 +96,7 @@ app.use(vhost('assets-*.example.com', staticapp)); app.listen(3000); ``` -### mit Verbindung für Benutzer-Subdomains verwenden +### mit connect für Benutzer-Subdomains verwenden ```js var connect = require('connect'); diff --git a/src/content/pages/de/resources/utils.mdx b/src/content/pages/de/resources/utils.mdx new file mode 100644 index 0000000000..b3b75e3ffb --- /dev/null +++ b/src/content/pages/de/resources/utils.mdx @@ -0,0 +1,22 @@ +--- +title: Express utilities +description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications. +--- + +## Express utility functions + +The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules +for utility functions that may be generally useful. + +| Utility modules | Beschreibung | +| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. | +| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. | +| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. | +| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. | +| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as \`\`/user/:name\` into a regular expression. | +| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. | +| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. | +| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. | + +For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp). diff --git a/src/content/pages/de/support.mdx b/src/content/pages/de/support.mdx new file mode 100644 index 0000000000..afdf027993 --- /dev/null +++ b/src/content/pages/de/support.mdx @@ -0,0 +1,23 @@ +--- +title: Versionsunterstützung +description: Finden Sie Informationen über den Support-Zeitplan für verschiedene Express.js Versionen, einschließlich der aktuellen Versionen und der End-of-Life-Richtlinien. +--- + +Nur die neueste Version einer der wichtigsten Release-Zeilen wird unterstützt. + +Versionen, die EOL (Ende des Lebens) _may_ sind, erhalten Updates für kritische Sicherheitslücken, aber das Express-Team bietet keine Garantie und plant keine Korrekturen für festgestellte Probleme zu beheben oder zu veröffentlichen. + +| Hauptversion | Minimale Node.js Version | Support-Startdatum | Support-Enddatum | +| -------------------------------------------------------------- | ------------------------ | ------------------ | ---------------- | +| [**v5.x**](/5x/api) | 18 | September 2024 | **Laufend** | +| [**v4.x**](/4x/api) | 0.10.0 | April 2014 | **Laufend** | +| [**v3.x**](/3x/api) | 0.8.0 | Oktober 2012 | Juli 2015 | +| [**v2.x**](https://github.com/expressjs/expressjs.com/tree/2x) | 0.4.1 | März 2011 | Juli 2012 | +| **v1.x** | 0.2.0 | Dezember 2010 | März 2011 | +| **v0.14.x** | 0.1.98 | Dezember 2010 | Dezember 2010 | + +## Kommerzielle Support-Optionen + +Wenn Sie nicht in der Lage sind, auf eine unterstützte Version von Express zu aktualisieren, wenden Sie sich bitte an einen unserer Partner, um Sicherheitsaktualisierungen zu erhalten: + +- [HeroDevs Never-Ending Support](https://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/src/content/pages/es/advanced/best-practice-performance.mdx b/src/content/pages/es/advanced/best-practice-performance.mdx new file mode 100644 index 0000000000..b064c27d72 --- /dev/null +++ b/src/content/pages/es/advanced/best-practice-performance.mdx @@ -0,0 +1,333 @@ +--- +title: 'Production best practices: performance and reliability' +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. +--- + +This article discusses performance and reliability best practices for Express applications deployed to production. + +This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: [things to do in your code](#things-to-do-in-your-code) (the dev part), and [things to do in your environment / setup](#things-to-do-in-your-environment--setup) (the ops part). + +## Things to do in your code + +Here are some things you can do in your code to improve your application's performance. + +### Use gzip compression + +Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. Por ejemplo: + +```cjs title="index.cjs" +const compression = require('compression'); +const express = require('express'); +const app = express(); + +app.use(compression()); +``` + +```mjs title="index.mjs" +import compression from 'compression'; +import express from 'express'; + +const app = express(); + +app.use(compression()); +``` + +For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) in the Nginx documentation. + +### Don't use synchronous functions + +Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production. + +Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup. + +You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli.html#--trace-sync-io) for more information. + +### Do logging correctly + +In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console.html#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. + +#### For debugging + +If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you? + +#### For app activity + +If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available. + +### Handle exceptions properly + +Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly. + +To ensure you handle all exceptions, use the following techniques: + +- [Use try-catch](#use-try-catch) +- [Use promises](#use-promises) + +Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain. + +For more on the fundamentals of error handling, see: + +- [Error Handling in Node.js](https://web.archive.org/web/20210619211351/https://www.joyent.com/node-js/production/design/errors) + +#### Use try-catch + +Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below. + +Here is an example of using try-catch to handle a potential process-crashing exception. +This middleware function accepts a query field parameter named "params" that is a JSON object. + +```js +app.get('/search', (req, res) => { + // Simulating async operation + setImmediate(() => { + const jsonStr = req.query.params; + try { + const jsonObj = JSON.parse(jsonStr); + res.send('Success'); + } catch (e) { + res.status(400).send('Invalid JSON string'); + } + }); +}); +``` + +However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions. + +#### Use promises + +When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)` + +```js +app.get('/', async (req, res, next) => { + const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error. + + res.send(data); +}); + +app.use((err, req, res, next) => { + res.status(err.status ?? 500).send({ error: err.message }); +}); +``` + +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: + +```js +app.use(async (req, res, next) => { + req.locals.user = await getUser(req); + + next(); // This will be called if the promise does not throw an error. +}); +``` + +Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware. + +#### What not to do + +One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable. + +Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process.html#event-uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error. + +We also don't recommend using [domains](https://nodejs.org/api/domain.html). It generally doesn't solve the problem and is a deprecated module. + +### Use worker threads for CPU-intensive tasks + +Node.js runs your JavaScript on a single thread, so a CPU-intensive operation (such as image processing, parsing or transforming large payloads, or cryptographic operations) can block the event loop and slow down every request your Express app is handling. If your app does CPU-bound work, you can run it in [worker threads](https://nodejs.org/api/worker_threads.html), which execute JavaScript in parallel within the same process, keeping the main thread free to serve requests. + +Each worker thread runs in its own JavaScript engine instance, so the data you pass to it through `workerData` or `postMessage` is copied, not shared. Copying large payloads has a cost of its own, which you can avoid by transferring objects such as `ArrayBuffer`s or by sharing memory explicitly with `SharedArrayBuffer`. Worker threads are not a replacement for [running your app in a cluster](#run-your-app-in-a-cluster), which scales your app across CPU cores by running multiple instances of it in separate processes. + +This example offloads an image-resizing task to a worker, where `resize-worker.js` receives the image via `workerData` and posts the result back when it's done: + +```js +const { Worker } = require('node:worker_threads'); + +app.post('/resize', (req, res, next) => { + const worker = new Worker('./resize-worker.js', { workerData: req.body.image }); + + worker.once('message', (result) => res.send(result)); + worker.once('error', next); +}); +``` + +Note that this example is kept simple for illustration: creating a worker thread is relatively expensive, so [the Node.js documentation recommends using a pool of workers](https://nodejs.org/api/worker_threads.html#worker-threads) instead of spawning a new one for every request. Create a fixed pool of workers at startup and dispatch tasks to them as requests come in, for example with a library like [piscina](https://www.npmjs.com/package/piscina): + +```js +const path = require('node:path'); +const Piscina = require('piscina'); + +const pool = new Piscina({ filename: path.resolve(__dirname, 'resize-worker.js') }); + +app.post('/resize', async (req, res, next) => { + try { + res.send(await pool.run(req.body.image)); + } catch (err) { + next(err); + } +}); +``` + +Here `resize-worker.js` simply exports the function to run in the pool, and piscina takes care of creating the workers, queueing tasks, and reusing threads across requests. + +For more guidance on keeping the event loop responsive, including when offloading work is worth its communication costs, see [Don't Block the Event Loop](https://nodejs.org/learn/asynchronous-work/dont-block-the-event-loop) in the Node.js documentation. + +## Things to do in your environment / setup + +Here are some things you can do in your system environment to improve your app's performance. + +### Set NODE_ENV to "production" + +The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. + +Setting NODE_ENV to "production" makes Express: + +- Cache view templates. +- Cache CSS files generated from CSS extensions. +- Generate less verbose error messages. + +[Tests indicate](https://web.archive.org/web/20250814011110/https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three! + +If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. + +In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here. + +With systemd, use the `Environment` directive in your unit file. Por ejemplo: + +```sh + +Environment=NODE_ENV=production +``` + +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). + +### Use the latest LTS version of Node.js + +Running your app on a recent Node.js release is one of the easiest ways to improve performance. Each new version of Node.js ships with cumulative improvements to the V8 JavaScript engine and the runtime itself, so the same Express app can handle significantly more requests simply by upgrading. Benchmarks such as NodeSource's [Node.js Performance Report](https://nodesource.com/pages/content-node-performance-report-wb.html) show how much throughput can improve from one Node.js version to the next. For production, use the latest [LTS release](https://nodejs.org/en/about/previous-releases) of Node.js, and keep it up to date as new versions come out. + +### Ensure your app automatically restarts + +In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by: + +- Using a process manager to restart the app (and Node) when it crashes. +- Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager. + +Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart. + +#### Use a process manager + +In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime. + +In addition to restarting your app when it crashes, a process manager can enable you to: + +- Gain insights into runtime performance and resource consumption. +- Modify settings dynamically to improve performance. +- Control clustering (pm2). + +Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management. + +#### Use an init system + +The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd). + +There are two ways to use init systems with your Express app: + +- Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach. +- Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager. + +##### Systemd + +Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system. + +A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `\` for your system and app: + +```sh +[Unit] +Description= + +[Service] +Type=simple +ExecStart=/usr/local/bin/node +WorkingDirectory= + +User=nobody +Group=nogroup + + +Environment=NODE_ENV=production + + +LimitNOFILE=infinity + + +LimitCORE=infinity + +StandardInput=null +StandardOutput=syslog +StandardError=syslog +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +For more information on systemd, see the [systemd reference (man page)](https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html). + +### Run your app in a cluster + +In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. + +![Balancing between application instances using the cluster API](/images/clustering.png) + +IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](https://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers. + +In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork(). + +#### Using Node's cluster module + +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. + +#### Using PM2 + +If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like). + +When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app. + +To enable cluster mode, start your application like so: + +```bash + +$ pm2 start npm --name my-app -i 4 -- start + +$ pm2 start npm --name my-app -i max -- start +``` + +This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start. + +Once running, the application can be scaled like so: + +```bash + +$ pm2 scale my-app +3 + +$ pm2 scale my-app 2 +``` + +For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. + +### Cache request results + +Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly. + +Use a caching server like [Varnish](https://www.varnish.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/c/nginx-caching)) to greatly improve the speed and performance of your app. + +### Use a load balancer + +No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance. + +A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). + +With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/). + +### Use a reverse proxy + +A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things. + +Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/src/content/pages/es/advanced/best-practice-security.mdx b/src/content/pages/es/advanced/best-practice-security.mdx index 1859d97445..652191a2c6 100644 --- a/src/content/pages/es/advanced/best-practice-security.mdx +++ b/src/content/pages/es/advanced/best-practice-security.mdx @@ -64,7 +64,7 @@ Aquí hay un ejemplo de comprobación de URLs antes de usar `res.redirect` o `re ```js app.use((req, res) => { try { - if (new Url(req.query.url).host !== 'example.com') { + if (new URL(req.query.url).host !== 'example.com') { return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`); } } catch (e) { diff --git a/src/content/pages/es/advanced/healthcheck-graceful-shutdown.mdx b/src/content/pages/es/advanced/healthcheck-graceful-shutdown.mdx new file mode 100644 index 0000000000..10fad29b91 --- /dev/null +++ b/src/content/pages/es/advanced/healthcheck-graceful-shutdown.mdx @@ -0,0 +1,28 @@ +--- +title: Health Checks and Graceful Shutdown +description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes. +--- + +## Graceful shutdown + +When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit. + +### Ejemplo + +```js +const server = app.listen(port); + +process.on('SIGTERM', () => { + debug('SIGTERM signal received: closing HTTP server'); + server.close(() => { + debug('HTTP server closed'); + }); +}); +``` + +## Health checks + +A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes//): + +- `liveness`, that determines when to restart a container. +- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers. diff --git a/src/content/pages/es/resources/utils.mdx b/src/content/pages/es/resources/utils.mdx new file mode 100644 index 0000000000..b26c64bf9c --- /dev/null +++ b/src/content/pages/es/resources/utils.mdx @@ -0,0 +1,22 @@ +--- +title: Express utilities +description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications. +--- + +## Express utility functions + +The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules +for utility functions that may be generally useful. + +| Utility modules | Descripción | +| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. | +| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. | +| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. | +| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. | +| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as \`\`/user/:name\` into a regular expression. | +| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. | +| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. | +| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. | + +For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp). diff --git a/src/content/pages/es/support.mdx b/src/content/pages/es/support.mdx new file mode 100644 index 0000000000..f3804919cc --- /dev/null +++ b/src/content/pages/es/support.mdx @@ -0,0 +1,23 @@ +--- +title: Soporte para versiones +description: Encuentre información sobre el programa de soporte para diferentes versiones de Express.js, incluyendo las versiones que se mantienen actualmente y las políticas de fin de su vida. +--- + +Sólo se admite la última versión de cualquier línea de lanzamiento mayor. + +Las versiones que son EOL (end-of-life) _pueden_ recibir actualizaciones para vulnerabilidades de seguridad críticas, pero el equipo de Express no ofrece ninguna garantía y no planea abordar o corregir versiones para ningún problema encontrado. + +| Versión principal | Versión mínima de Node.js | Inicio de Soporte | Fecha de fin de soporte | +| -------------------------------------------------------------- | ------------------------- | ------------------ | ----------------------- | +| [**v5.x**](/5x/api) | 18 | Septiembre de 2024 | **en curso** | +| [**v4.x**](/4x/api) | 0.10.0 | Abril de 2014 | **en curso** | +| [**v3.x**](/3x/api) | 0.8.0 | Octubre de 2012 | Julio de 2015 | +| [**v2.x**](https://github.com/expressjs/expressjs.com/tree/2x) | 0.4.1 | Marzo de 2011 | Julio de 2012 | +| **v1.x** | 0.2.0 | Diciembre 2010 | Marzo de 2011 | +| **v0.14.x** | 0.1.98 | Diciembre 2010 | Diciembre 2010 | + +## Opciones de soporte comercial + +Si no puede actualizar a una versión soportada de Express, póngase en contacto con uno de nuestros socios para recibir actualizaciones de seguridad: + +- [HeroDevs Never-Ending Support](https://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/src/content/pages/fr/advanced/best-practice-performance.mdx b/src/content/pages/fr/advanced/best-practice-performance.mdx new file mode 100644 index 0000000000..e8e96522a6 --- /dev/null +++ b/src/content/pages/fr/advanced/best-practice-performance.mdx @@ -0,0 +1,333 @@ +--- +title: 'Production best practices: performance and reliability' +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. +--- + +This article discusses performance and reliability best practices for Express applications deployed to production. + +This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: [things to do in your code](#things-to-do-in-your-code) (the dev part), and [things to do in your environment / setup](#things-to-do-in-your-environment--setup) (the ops part). + +## Things to do in your code + +Here are some things you can do in your code to improve your application's performance. + +### Use gzip compression + +Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. Par exemple : + +```cjs title="index.cjs" +const compression = require('compression'); +const express = require('express'); +const app = express(); + +app.use(compression()); +``` + +```mjs title="index.mjs" +import compression from 'compression'; +import express from 'express'; + +const app = express(); + +app.use(compression()); +``` + +For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) in the Nginx documentation. + +### Don't use synchronous functions + +Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production. + +Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup. + +You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli.html#--trace-sync-io) for more information. + +### Do logging correctly + +In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console.html#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. + +#### For debugging + +If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you? + +#### For app activity + +If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available. + +### Handle exceptions properly + +Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly. + +To ensure you handle all exceptions, use the following techniques: + +- [Use try-catch](#use-try-catch) +- [Use promises](#use-promises) + +Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain. + +For more on the fundamentals of error handling, see: + +- [Error Handling in Node.js](https://web.archive.org/web/20210619211351/https://www.joyent.com/node-js/production/design/errors) + +#### Use try-catch + +Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below. + +Here is an example of using try-catch to handle a potential process-crashing exception. +This middleware function accepts a query field parameter named "params" that is a JSON object. + +```js +app.get('/search', (req, res) => { + // Simulating async operation + setImmediate(() => { + const jsonStr = req.query.params; + try { + const jsonObj = JSON.parse(jsonStr); + res.send('Success'); + } catch (e) { + res.status(400).send('Invalid JSON string'); + } + }); +}); +``` + +However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions. + +#### Use promises + +When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)` + +```js +app.get('/', async (req, res, next) => { + const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error. + + res.send(data); +}); + +app.use((err, req, res, next) => { + res.status(err.status ?? 500).send({ error: err.message }); +}); +``` + +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: + +```js +app.use(async (req, res, next) => { + req.locals.user = await getUser(req); + + next(); // This will be called if the promise does not throw an error. +}); +``` + +Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware. + +#### What not to do + +One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable. + +Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process.html#event-uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error. + +We also don't recommend using [domains](https://nodejs.org/api/domain.html). It generally doesn't solve the problem and is a deprecated module. + +### Use worker threads for CPU-intensive tasks + +Node.js runs your JavaScript on a single thread, so a CPU-intensive operation (such as image processing, parsing or transforming large payloads, or cryptographic operations) can block the event loop and slow down every request your Express app is handling. If your app does CPU-bound work, you can run it in [worker threads](https://nodejs.org/api/worker_threads.html), which execute JavaScript in parallel within the same process, keeping the main thread free to serve requests. + +Each worker thread runs in its own JavaScript engine instance, so the data you pass to it through `workerData` or `postMessage` is copied, not shared. Copying large payloads has a cost of its own, which you can avoid by transferring objects such as `ArrayBuffer`s or by sharing memory explicitly with `SharedArrayBuffer`. Worker threads are not a replacement for [running your app in a cluster](#run-your-app-in-a-cluster), which scales your app across CPU cores by running multiple instances of it in separate processes. + +This example offloads an image-resizing task to a worker, where `resize-worker.js` receives the image via `workerData` and posts the result back when it's done: + +```js +const { Worker } = require('node:worker_threads'); + +app.post('/resize', (req, res, next) => { + const worker = new Worker('./resize-worker.js', { workerData: req.body.image }); + + worker.once('message', (result) => res.send(result)); + worker.once('error', next); +}); +``` + +Note that this example is kept simple for illustration: creating a worker thread is relatively expensive, so [the Node.js documentation recommends using a pool of workers](https://nodejs.org/api/worker_threads.html#worker-threads) instead of spawning a new one for every request. Create a fixed pool of workers at startup and dispatch tasks to them as requests come in, for example with a library like [piscina](https://www.npmjs.com/package/piscina): + +```js +const path = require('node:path'); +const Piscina = require('piscina'); + +const pool = new Piscina({ filename: path.resolve(__dirname, 'resize-worker.js') }); + +app.post('/resize', async (req, res, next) => { + try { + res.send(await pool.run(req.body.image)); + } catch (err) { + next(err); + } +}); +``` + +Here `resize-worker.js` simply exports the function to run in the pool, and piscina takes care of creating the workers, queueing tasks, and reusing threads across requests. + +For more guidance on keeping the event loop responsive, including when offloading work is worth its communication costs, see [Don't Block the Event Loop](https://nodejs.org/learn/asynchronous-work/dont-block-the-event-loop) in the Node.js documentation. + +## Things to do in your environment / setup + +Here are some things you can do in your system environment to improve your app's performance. + +### Set NODE_ENV to "production" + +The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. + +Setting NODE_ENV to "production" makes Express: + +- Cache view templates. +- Cache CSS files generated from CSS extensions. +- Generate less verbose error messages. + +[Tests indicate](https://web.archive.org/web/20250814011110/https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three! + +If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. + +In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here. + +With systemd, use the `Environment` directive in your unit file. Par exemple : + +```sh + +Environment=NODE_ENV=production +``` + +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). + +### Use the latest LTS version of Node.js + +Running your app on a recent Node.js release is one of the easiest ways to improve performance. Each new version of Node.js ships with cumulative improvements to the V8 JavaScript engine and the runtime itself, so the same Express app can handle significantly more requests simply by upgrading. Benchmarks such as NodeSource's [Node.js Performance Report](https://nodesource.com/pages/content-node-performance-report-wb.html) show how much throughput can improve from one Node.js version to the next. For production, use the latest [LTS release](https://nodejs.org/en/about/previous-releases) of Node.js, and keep it up to date as new versions come out. + +### Ensure your app automatically restarts + +In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by: + +- Using a process manager to restart the app (and Node) when it crashes. +- Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager. + +Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart. + +#### Use a process manager + +In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime. + +In addition to restarting your app when it crashes, a process manager can enable you to: + +- Gain insights into runtime performance and resource consumption. +- Modify settings dynamically to improve performance. +- Control clustering (pm2). + +Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management. + +#### Use an init system + +The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd). + +There are two ways to use init systems with your Express app: + +- Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach. +- Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager. + +##### Systemd + +Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system. + +A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `\` for your system and app: + +```sh +[Unit] +Description= + +[Service] +Type=simple +ExecStart=/usr/local/bin/node +WorkingDirectory= + +User=nobody +Group=nogroup + + +Environment=NODE_ENV=production + + +LimitNOFILE=infinity + + +LimitCORE=infinity + +StandardInput=null +StandardOutput=syslog +StandardError=syslog +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +For more information on systemd, see the [systemd reference (man page)](https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html). + +### Run your app in a cluster + +In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. + +![Balancing between application instances using the cluster API](/images/clustering.png) + +IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](https://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers. + +In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork(). + +#### Using Node's cluster module + +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. + +#### Using PM2 + +If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like). + +When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app. + +To enable cluster mode, start your application like so: + +```bash + +$ pm2 start npm --name my-app -i 4 -- start + +$ pm2 start npm --name my-app -i max -- start +``` + +This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start. + +Once running, the application can be scaled like so: + +```bash + +$ pm2 scale my-app +3 + +$ pm2 scale my-app 2 +``` + +For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. + +### Cache request results + +Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly. + +Use a caching server like [Varnish](https://www.varnish.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/c/nginx-caching)) to greatly improve the speed and performance of your app. + +### Use a load balancer + +No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance. + +A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). + +With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/). + +### Use a reverse proxy + +A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things. + +Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/src/content/pages/fr/advanced/best-practice-security.mdx b/src/content/pages/fr/advanced/best-practice-security.mdx index cc3c58052e..8f15bb49db 100644 --- a/src/content/pages/fr/advanced/best-practice-security.mdx +++ b/src/content/pages/fr/advanced/best-practice-security.mdx @@ -64,7 +64,7 @@ Voici un exemple de vérification des URLs avant d'utiliser `res.redirect` ou `r ```js app.use((req, res) => { try { - if (new Url(req.query.url).host !== 'example.com') { + if (new URL(req.query.url).host !== 'example.com') { return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`); } } catch (e) { diff --git a/src/content/pages/fr/advanced/healthcheck-graceful-shutdown.mdx b/src/content/pages/fr/advanced/healthcheck-graceful-shutdown.mdx new file mode 100644 index 0000000000..3c28a517fc --- /dev/null +++ b/src/content/pages/fr/advanced/healthcheck-graceful-shutdown.mdx @@ -0,0 +1,28 @@ +--- +title: Health Checks and Graceful Shutdown +description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes. +--- + +## Graceful shutdown + +When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit. + +### Exemple + +```js +const server = app.listen(port); + +process.on('SIGTERM', () => { + debug('SIGTERM signal received: closing HTTP server'); + server.close(() => { + debug('HTTP server closed'); + }); +}); +``` + +## Health checks + +A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes//): + +- `liveness`, that determines when to restart a container. +- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers. diff --git a/src/content/pages/fr/resources/utils.mdx b/src/content/pages/fr/resources/utils.mdx new file mode 100644 index 0000000000..64f75c9be4 --- /dev/null +++ b/src/content/pages/fr/resources/utils.mdx @@ -0,0 +1,22 @@ +--- +title: Express utilities +description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications. +--- + +## Express utility functions + +The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules +for utility functions that may be generally useful. + +| Utility modules | Libellé | +| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. | +| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. | +| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. | +| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. | +| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as \`\`/user/:name\` into a regular expression. | +| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. | +| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. | +| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. | + +For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp). diff --git a/src/content/pages/fr/support.mdx b/src/content/pages/fr/support.mdx new file mode 100644 index 0000000000..93c2d7bc52 --- /dev/null +++ b/src/content/pages/fr/support.mdx @@ -0,0 +1,23 @@ +--- +title: Support de la version +description: Trouvez des informations sur le calendrier de support des différentes versions de Express.js, y compris les versions actuellement maintenues et les politiques de fin de vie. +--- + +Seule la dernière version d'une ligne de publication majeure est prise en charge. + +Les versions qui sont EdlV (fin de vie) _peuvent_ recevoir des mises à jour pour les vulnérabilités critiques de sécurité, mais l'équipe Express n'offre aucune garantie et ne prévoit pas de résoudre ou de corriger les problèmes rencontrés. + +| Version majeure | Version minimale de Node.js | Date de début du support | Date de fin du support | +| -------------------------------------------------------------- | --------------------------- | ------------------------ | ---------------------- | +| [**v5.x**](/5x/api) | 18 | Septembre 2024 | **en cours** | +| [**v4.x**](/4x/api) | 0.10.0 | Avril 2014 | **en cours** | +| [**v3.x**](/3x/api) | 0.8.0 | Octobre 2012 | Juillet 2015 | +| [**v2.x**](https://github.com/expressjs/expressjs.com/tree/2x) | 0.4.1 | Mars 2011 | Juillet 2012 | +| **v1.x** | 0.2.0 | Décembre 2010 | Mars 2011 | +| **v0.14.x** | 0.1.98 | Décembre 2010 | Décembre 2010 | + +## Options de support commercial + +Si vous ne pouvez pas mettre à jour une version prise en charge de Express, veuillez contacter l'un de nos partenaires pour recevoir les mises à jour de sécurité : + +- [HeroDevs Never-Ending Support](https://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/src/content/pages/it/advanced/best-practice-performance.mdx b/src/content/pages/it/advanced/best-practice-performance.mdx new file mode 100644 index 0000000000..73c3264033 --- /dev/null +++ b/src/content/pages/it/advanced/best-practice-performance.mdx @@ -0,0 +1,333 @@ +--- +title: 'Production best practices: performance and reliability' +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. +--- + +This article discusses performance and reliability best practices for Express applications deployed to production. + +This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: [things to do in your code](#things-to-do-in-your-code) (the dev part), and [things to do in your environment / setup](#things-to-do-in-your-environment--setup) (the ops part). + +## Things to do in your code + +Here are some things you can do in your code to improve your application's performance. + +### Use gzip compression + +Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. Per esempio: + +```cjs title="index.cjs" +const compression = require('compression'); +const express = require('express'); +const app = express(); + +app.use(compression()); +``` + +```mjs title="index.mjs" +import compression from 'compression'; +import express from 'express'; + +const app = express(); + +app.use(compression()); +``` + +For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) in the Nginx documentation. + +### Don't use synchronous functions + +Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production. + +Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup. + +You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli.html#--trace-sync-io) for more information. + +### Do logging correctly + +In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console.html#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. + +#### For debugging + +If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you? + +#### For app activity + +If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available. + +### Handle exceptions properly + +Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly. + +To ensure you handle all exceptions, use the following techniques: + +- [Use try-catch](#use-try-catch) +- [Use promises](#use-promises) + +Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain. + +For more on the fundamentals of error handling, see: + +- [Error Handling in Node.js](https://web.archive.org/web/20210619211351/https://www.joyent.com/node-js/production/design/errors) + +#### Use try-catch + +Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below. + +Here is an example of using try-catch to handle a potential process-crashing exception. +This middleware function accepts a query field parameter named "params" that is a JSON object. + +```js +app.get('/search', (req, res) => { + // Simulating async operation + setImmediate(() => { + const jsonStr = req.query.params; + try { + const jsonObj = JSON.parse(jsonStr); + res.send('Success'); + } catch (e) { + res.status(400).send('Invalid JSON string'); + } + }); +}); +``` + +However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions. + +#### Use promises + +When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)` + +```js +app.get('/', async (req, res, next) => { + const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error. + + res.send(data); +}); + +app.use((err, req, res, next) => { + res.status(err.status ?? 500).send({ error: err.message }); +}); +``` + +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: + +```js +app.use(async (req, res, next) => { + req.locals.user = await getUser(req); + + next(); // This will be called if the promise does not throw an error. +}); +``` + +Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware. + +#### What not to do + +One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable. + +Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process.html#event-uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error. + +We also don't recommend using [domains](https://nodejs.org/api/domain.html). It generally doesn't solve the problem and is a deprecated module. + +### Use worker threads for CPU-intensive tasks + +Node.js runs your JavaScript on a single thread, so a CPU-intensive operation (such as image processing, parsing or transforming large payloads, or cryptographic operations) can block the event loop and slow down every request your Express app is handling. If your app does CPU-bound work, you can run it in [worker threads](https://nodejs.org/api/worker_threads.html), which execute JavaScript in parallel within the same process, keeping the main thread free to serve requests. + +Each worker thread runs in its own JavaScript engine instance, so the data you pass to it through `workerData` or `postMessage` is copied, not shared. Copying large payloads has a cost of its own, which you can avoid by transferring objects such as `ArrayBuffer`s or by sharing memory explicitly with `SharedArrayBuffer`. Worker threads are not a replacement for [running your app in a cluster](#run-your-app-in-a-cluster), which scales your app across CPU cores by running multiple instances of it in separate processes. + +This example offloads an image-resizing task to a worker, where `resize-worker.js` receives the image via `workerData` and posts the result back when it's done: + +```js +const { Worker } = require('node:worker_threads'); + +app.post('/resize', (req, res, next) => { + const worker = new Worker('./resize-worker.js', { workerData: req.body.image }); + + worker.once('message', (result) => res.send(result)); + worker.once('error', next); +}); +``` + +Note that this example is kept simple for illustration: creating a worker thread is relatively expensive, so [the Node.js documentation recommends using a pool of workers](https://nodejs.org/api/worker_threads.html#worker-threads) instead of spawning a new one for every request. Create a fixed pool of workers at startup and dispatch tasks to them as requests come in, for example with a library like [piscina](https://www.npmjs.com/package/piscina): + +```js +const path = require('node:path'); +const Piscina = require('piscina'); + +const pool = new Piscina({ filename: path.resolve(__dirname, 'resize-worker.js') }); + +app.post('/resize', async (req, res, next) => { + try { + res.send(await pool.run(req.body.image)); + } catch (err) { + next(err); + } +}); +``` + +Here `resize-worker.js` simply exports the function to run in the pool, and piscina takes care of creating the workers, queueing tasks, and reusing threads across requests. + +For more guidance on keeping the event loop responsive, including when offloading work is worth its communication costs, see [Don't Block the Event Loop](https://nodejs.org/learn/asynchronous-work/dont-block-the-event-loop) in the Node.js documentation. + +## Things to do in your environment / setup + +Here are some things you can do in your system environment to improve your app's performance. + +### Set NODE_ENV to "production" + +The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. + +Setting NODE_ENV to "production" makes Express: + +- Cache view templates. +- Cache CSS files generated from CSS extensions. +- Generate less verbose error messages. + +[Tests indicate](https://web.archive.org/web/20250814011110/https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three! + +If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. + +In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here. + +With systemd, use the `Environment` directive in your unit file. Per esempio: + +```sh + +Environment=NODE_ENV=production +``` + +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). + +### Use the latest LTS version of Node.js + +Running your app on a recent Node.js release is one of the easiest ways to improve performance. Each new version of Node.js ships with cumulative improvements to the V8 JavaScript engine and the runtime itself, so the same Express app can handle significantly more requests simply by upgrading. Benchmarks such as NodeSource's [Node.js Performance Report](https://nodesource.com/pages/content-node-performance-report-wb.html) show how much throughput can improve from one Node.js version to the next. For production, use the latest [LTS release](https://nodejs.org/en/about/previous-releases) of Node.js, and keep it up to date as new versions come out. + +### Ensure your app automatically restarts + +In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by: + +- Using a process manager to restart the app (and Node) when it crashes. +- Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager. + +Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart. + +#### Use a process manager + +In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime. + +In addition to restarting your app when it crashes, a process manager can enable you to: + +- Gain insights into runtime performance and resource consumption. +- Modify settings dynamically to improve performance. +- Control clustering (pm2). + +Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management. + +#### Use an init system + +The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd). + +There are two ways to use init systems with your Express app: + +- Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach. +- Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager. + +##### Systemd + +Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system. + +A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `\` for your system and app: + +```sh +[Unit] +Description= + +[Service] +Type=simple +ExecStart=/usr/local/bin/node +WorkingDirectory= + +User=nobody +Group=nogroup + + +Environment=NODE_ENV=production + + +LimitNOFILE=infinity + + +LimitCORE=infinity + +StandardInput=null +StandardOutput=syslog +StandardError=syslog +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +For more information on systemd, see the [systemd reference (man page)](https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html). + +### Run your app in a cluster + +In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. + +![Balancing between application instances using the cluster API](/images/clustering.png) + +IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](https://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers. + +In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork(). + +#### Using Node's cluster module + +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. + +#### Using PM2 + +If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like). + +When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app. + +To enable cluster mode, start your application like so: + +```bash + +$ pm2 start npm --name my-app -i 4 -- start + +$ pm2 start npm --name my-app -i max -- start +``` + +This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start. + +Once running, the application can be scaled like so: + +```bash + +$ pm2 scale my-app +3 + +$ pm2 scale my-app 2 +``` + +For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. + +### Cache request results + +Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly. + +Use a caching server like [Varnish](https://www.varnish.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/c/nginx-caching)) to greatly improve the speed and performance of your app. + +### Use a load balancer + +No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance. + +A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). + +With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/). + +### Use a reverse proxy + +A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things. + +Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/src/content/pages/it/advanced/best-practice-security.mdx b/src/content/pages/it/advanced/best-practice-security.mdx index 7628d34278..5257eacf90 100644 --- a/src/content/pages/it/advanced/best-practice-security.mdx +++ b/src/content/pages/it/advanced/best-practice-security.mdx @@ -64,7 +64,7 @@ Ecco un esempio di controllo degli URL prima di usare `res.redirect` o `res.loca ```js app.use((req, res) => { try { - if (new Url(req.query.url).host !== 'example.com') { + if (new URL(req.query.url).host !== 'example.com') { return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`); } } catch (e) { diff --git a/src/content/pages/it/advanced/healthcheck-graceful-shutdown.mdx b/src/content/pages/it/advanced/healthcheck-graceful-shutdown.mdx new file mode 100644 index 0000000000..799ef54c94 --- /dev/null +++ b/src/content/pages/it/advanced/healthcheck-graceful-shutdown.mdx @@ -0,0 +1,28 @@ +--- +title: Health Checks and Graceful Shutdown +description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes. +--- + +## Graceful shutdown + +When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit. + +### Esempio + +```js +const server = app.listen(port); + +process.on('SIGTERM', () => { + debug('SIGTERM signal received: closing HTTP server'); + server.close(() => { + debug('HTTP server closed'); + }); +}); +``` + +## Health checks + +A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes//): + +- `liveness`, that determines when to restart a container. +- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers. diff --git a/src/content/pages/it/resources/utils.mdx b/src/content/pages/it/resources/utils.mdx new file mode 100644 index 0000000000..148e0110fb --- /dev/null +++ b/src/content/pages/it/resources/utils.mdx @@ -0,0 +1,22 @@ +--- +title: Express utilities +description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications. +--- + +## Express utility functions + +The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules +for utility functions that may be generally useful. + +| Utility modules | Descrizione | +| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. | +| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. | +| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. | +| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. | +| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as \`\`/user/:name\` into a regular expression. | +| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. | +| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. | +| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. | + +For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp). diff --git a/src/content/pages/it/support.mdx b/src/content/pages/it/support.mdx new file mode 100644 index 0000000000..4fc0ebeed8 --- /dev/null +++ b/src/content/pages/it/support.mdx @@ -0,0 +1,23 @@ +--- +title: Supporto Versione +description: Trova informazioni sul programma di supporto per le diverse versioni di Express.js, comprese le versioni attualmente mantenute e le politiche di fine vita. +--- + +È supportata solo l'ultima versione di una data linea di rilascio principale. + +Versioni che sono EOL (end-of-life) _may_ ricevere aggiornamenti per le vulnerabilità di sicurezza critiche, ma il team Express non offre alcuna garanzia e non prevede di affrontare o risolvere i problemi riscontrati. + +| Versione Maggiore | Versione Minima Node.js | Data Inizio Supporto | Data Di Fine Supporto | +| -------------------------------------------------------------- | ----------------------- | -------------------- | --------------------- | +| [**v5.x**](/5x/api) | 18 | Settembre 2024 | **in corso** | +| [**v4.x**](/4x/api) | 0.10.0 | Aprile 2014 | **in corso** | +| [**v3.x**](/3x/api) | 0.8.0 | Ottobre 2012 | Luglio 2015 | +| [**v2.x**](https://github.com/expressjs/expressjs.com/tree/2x) | 0.4.1 | Marzo 2011 | Luglio 2012 | +| **v1.x** | 0.2.0 | Dicembre 2010 | Marzo 2011 | +| **v0.14.x** | 0.1.98 | Dicembre 2010 | Dicembre 2010 | + +## Opzioni Di Supporto Commerciale + +Se non riesci ad aggiornare ad una versione supportata di Express, contatta uno dei nostri partner per ricevere aggiornamenti di sicurezza: + +- [HeroDevs Never-Ending Support](https://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/src/content/pages/ja/advanced/best-practice-performance.mdx b/src/content/pages/ja/advanced/best-practice-performance.mdx new file mode 100644 index 0000000000..ba05f0c04d --- /dev/null +++ b/src/content/pages/ja/advanced/best-practice-performance.mdx @@ -0,0 +1,333 @@ +--- +title: 'Production best practices: performance and reliability' +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. +--- + +This article discusses performance and reliability best practices for Express applications deployed to production. + +This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: [things to do in your code](#things-to-do-in-your-code) (the dev part), and [things to do in your environment / setup](#things-to-do-in-your-environment--setup) (the ops part). + +## Things to do in your code + +Here are some things you can do in your code to improve your application's performance. + +### Use gzip compression + +Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. 例: + +```cjs title="index.cjs" +const compression = require('compression'); +const express = require('express'); +const app = express(); + +app.use(compression()); +``` + +```mjs title="index.mjs" +import compression from 'compression'; +import express from 'express'; + +const app = express(); + +app.use(compression()); +``` + +For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) in the Nginx documentation. + +### Don't use synchronous functions + +Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production. + +Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup. + +You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli.html#--trace-sync-io) for more information. + +### Do logging correctly + +In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console.html#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. + +#### For debugging + +If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you? + +#### For app activity + +If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available. + +### Handle exceptions properly + +Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly. + +To ensure you handle all exceptions, use the following techniques: + +- [Use try-catch](#use-try-catch) +- [Use promises](#use-promises) + +Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain. + +For more on the fundamentals of error handling, see: + +- [Error Handling in Node.js](https://web.archive.org/web/20210619211351/https://www.joyent.com/node-js/production/design/errors) + +#### Use try-catch + +Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below. + +Here is an example of using try-catch to handle a potential process-crashing exception. +This middleware function accepts a query field parameter named "params" that is a JSON object. + +```js +app.get('/search', (req, res) => { + // Simulating async operation + setImmediate(() => { + const jsonStr = req.query.params; + try { + const jsonObj = JSON.parse(jsonStr); + res.send('Success'); + } catch (e) { + res.status(400).send('Invalid JSON string'); + } + }); +}); +``` + +However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions. + +#### Use promises + +When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)` + +```js +app.get('/', async (req, res, next) => { + const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error. + + res.send(data); +}); + +app.use((err, req, res, next) => { + res.status(err.status ?? 500).send({ error: err.message }); +}); +``` + +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: + +```js +app.use(async (req, res, next) => { + req.locals.user = await getUser(req); + + next(); // This will be called if the promise does not throw an error. +}); +``` + +Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware. + +#### What not to do + +One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable. + +Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process.html#event-uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error. + +We also don't recommend using [domains](https://nodejs.org/api/domain.html). It generally doesn't solve the problem and is a deprecated module. + +### Use worker threads for CPU-intensive tasks + +Node.js runs your JavaScript on a single thread, so a CPU-intensive operation (such as image processing, parsing or transforming large payloads, or cryptographic operations) can block the event loop and slow down every request your Express app is handling. If your app does CPU-bound work, you can run it in [worker threads](https://nodejs.org/api/worker_threads.html), which execute JavaScript in parallel within the same process, keeping the main thread free to serve requests. + +Each worker thread runs in its own JavaScript engine instance, so the data you pass to it through `workerData` or `postMessage` is copied, not shared. Copying large payloads has a cost of its own, which you can avoid by transferring objects such as `ArrayBuffer`s or by sharing memory explicitly with `SharedArrayBuffer`. Worker threads are not a replacement for [running your app in a cluster](#run-your-app-in-a-cluster), which scales your app across CPU cores by running multiple instances of it in separate processes. + +This example offloads an image-resizing task to a worker, where `resize-worker.js` receives the image via `workerData` and posts the result back when it's done: + +```js +const { Worker } = require('node:worker_threads'); + +app.post('/resize', (req, res, next) => { + const worker = new Worker('./resize-worker.js', { workerData: req.body.image }); + + worker.once('message', (result) => res.send(result)); + worker.once('error', next); +}); +``` + +Note that this example is kept simple for illustration: creating a worker thread is relatively expensive, so [the Node.js documentation recommends using a pool of workers](https://nodejs.org/api/worker_threads.html#worker-threads) instead of spawning a new one for every request. Create a fixed pool of workers at startup and dispatch tasks to them as requests come in, for example with a library like [piscina](https://www.npmjs.com/package/piscina): + +```js +const path = require('node:path'); +const Piscina = require('piscina'); + +const pool = new Piscina({ filename: path.resolve(__dirname, 'resize-worker.js') }); + +app.post('/resize', async (req, res, next) => { + try { + res.send(await pool.run(req.body.image)); + } catch (err) { + next(err); + } +}); +``` + +Here `resize-worker.js` simply exports the function to run in the pool, and piscina takes care of creating the workers, queueing tasks, and reusing threads across requests. + +For more guidance on keeping the event loop responsive, including when offloading work is worth its communication costs, see [Don't Block the Event Loop](https://nodejs.org/learn/asynchronous-work/dont-block-the-event-loop) in the Node.js documentation. + +## Things to do in your environment / setup + +Here are some things you can do in your system environment to improve your app's performance. + +### Set NODE_ENV to "production" + +The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. + +Setting NODE_ENV to "production" makes Express: + +- Cache view templates. +- Cache CSS files generated from CSS extensions. +- Generate less verbose error messages. + +[Tests indicate](https://web.archive.org/web/20250814011110/https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three! + +If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. + +In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here. + +With systemd, use the `Environment` directive in your unit file. 例: + +```sh + +Environment=NODE_ENV=production +``` + +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). + +### Use the latest LTS version of Node.js + +Running your app on a recent Node.js release is one of the easiest ways to improve performance. Each new version of Node.js ships with cumulative improvements to the V8 JavaScript engine and the runtime itself, so the same Express app can handle significantly more requests simply by upgrading. Benchmarks such as NodeSource's [Node.js Performance Report](https://nodesource.com/pages/content-node-performance-report-wb.html) show how much throughput can improve from one Node.js version to the next. For production, use the latest [LTS release](https://nodejs.org/en/about/previous-releases) of Node.js, and keep it up to date as new versions come out. + +### Ensure your app automatically restarts + +In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by: + +- Using a process manager to restart the app (and Node) when it crashes. +- Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager. + +Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart. + +#### Use a process manager + +In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime. + +In addition to restarting your app when it crashes, a process manager can enable you to: + +- Gain insights into runtime performance and resource consumption. +- Modify settings dynamically to improve performance. +- Control clustering (pm2). + +Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management. + +#### Use an init system + +The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd). + +There are two ways to use init systems with your Express app: + +- Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach. +- Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager. + +##### Systemd + +Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system. + +A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `\` for your system and app: + +```sh +[Unit] +Description= + +[Service] +Type=simple +ExecStart=/usr/local/bin/node +WorkingDirectory= + +User=nobody +Group=nogroup + + +Environment=NODE_ENV=production + + +LimitNOFILE=infinity + + +LimitCORE=infinity + +StandardInput=null +StandardOutput=syslog +StandardError=syslog +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +For more information on systemd, see the [systemd reference (man page)](https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html). + +### Run your app in a cluster + +In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. + +![Balancing between application instances using the cluster API](/images/clustering.png) + +IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](https://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers. + +In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork(). + +#### Using Node's cluster module + +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. + +#### Using PM2 + +If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like). + +When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app. + +To enable cluster mode, start your application like so: + +```bash + +$ pm2 start npm --name my-app -i 4 -- start + +$ pm2 start npm --name my-app -i max -- start +``` + +This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start. + +Once running, the application can be scaled like so: + +```bash + +$ pm2 scale my-app +3 + +$ pm2 scale my-app 2 +``` + +For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. + +### Cache request results + +Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly. + +Use a caching server like [Varnish](https://www.varnish.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/c/nginx-caching)) to greatly improve the speed and performance of your app. + +### Use a load balancer + +No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance. + +A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). + +With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/). + +### Use a reverse proxy + +A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things. + +Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/src/content/pages/ja/advanced/best-practice-security.mdx b/src/content/pages/ja/advanced/best-practice-security.mdx index 77ab6f0be4..59a214187d 100644 --- a/src/content/pages/ja/advanced/best-practice-security.mdx +++ b/src/content/pages/ja/advanced/best-practice-security.mdx @@ -65,7 +65,7 @@ Webアプリケーションの場合、最も重要なセキュリティ要件 ```js app.use((req, res) => { try { - if (new Url(req.query.url).host !== 'example.com') { + if (new URL(req.query.url).host !== 'example.com') { return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`); } } catch (e) { diff --git a/src/content/pages/ja/advanced/healthcheck-graceful-shutdown.mdx b/src/content/pages/ja/advanced/healthcheck-graceful-shutdown.mdx new file mode 100644 index 0000000000..606aa22729 --- /dev/null +++ b/src/content/pages/ja/advanced/healthcheck-graceful-shutdown.mdx @@ -0,0 +1,28 @@ +--- +title: Health Checks and Graceful Shutdown +description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes. +--- + +## Graceful shutdown + +When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit. + +### 例 + +```js +const server = app.listen(port); + +process.on('SIGTERM', () => { + debug('SIGTERM signal received: closing HTTP server'); + server.close(() => { + debug('HTTP server closed'); + }); +}); +``` + +## Health checks + +A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes//): + +- `liveness`, that determines when to restart a container. +- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers. diff --git a/src/content/pages/ja/resources/middleware/compression.mdx b/src/content/pages/ja/resources/middleware/compression.mdx index 826b3c6cc1..a77e0a2c18 100644 --- a/src/content/pages/ja/resources/middleware/compression.mdx +++ b/src/content/pages/ja/resources/middleware/compression.mdx @@ -1,5 +1,5 @@ --- -title: compressmiddleware +title: compression middleware description: Node.js compression ミドルウェア --- diff --git a/src/content/pages/ja/resources/middleware/errorhandler.mdx b/src/content/pages/ja/resources/middleware/errorhandler.mdx index 50432e7ef1..f7cce2518d 100644 --- a/src/content/pages/ja/resources/middleware/errorhandler.mdx +++ b/src/content/pages/ja/resources/middleware/errorhandler.mdx @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa diff --git a/src/content/pages/ja/resources/middleware/method-override.mdx b/src/content/pages/ja/resources/middleware/method-override.mdx index ca01f733c1..3800552337 100644 --- a/src/content/pages/ja/resources/middleware/method-override.mdx +++ b/src/content/pages/ja/resources/middleware/method-override.mdx @@ -1,5 +1,5 @@ --- -title: method-overridemiddleware +title: method-override middleware description: HTTP 動詞を上書き --- @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa diff --git a/src/content/pages/ja/resources/middleware/response-time.mdx b/src/content/pages/ja/resources/middleware/response-time.mdx index 0559241876..5887f910d1 100644 --- a/src/content/pages/ja/resources/middleware/response-time.mdx +++ b/src/content/pages/ja/resources/middleware/response-time.mdx @@ -9,8 +9,8 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa Node.js サーバーの応答時間。 diff --git a/src/content/pages/ja/resources/middleware/serve-favicon.mdx b/src/content/pages/ja/resources/middleware/serve-favicon.mdx index 9be737db28..4c06bc5d8a 100644 --- a/src/content/pages/ja/resources/middleware/serve-favicon.mdx +++ b/src/content/pages/ja/resources/middleware/serve-favicon.mdx @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa diff --git a/src/content/pages/ja/resources/middleware/serve-static.mdx b/src/content/pages/ja/resources/middleware/serve-static.mdx index 41f939e7be..216aa7d6f5 100644 --- a/src/content/pages/ja/resources/middleware/serve-static.mdx +++ b/src/content/pages/ja/resources/middleware/serve-static.mdx @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa diff --git a/src/content/pages/ja/resources/middleware/timeout.mdx b/src/content/pages/ja/resources/middleware/timeout.mdx index 63cce0b77e..68af7201ab 100644 --- a/src/content/pages/ja/resources/middleware/timeout.mdx +++ b/src/content/pages/ja/resources/middleware/timeout.mdx @@ -9,7 +9,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa diff --git a/src/content/pages/ja/resources/utils.mdx b/src/content/pages/ja/resources/utils.mdx new file mode 100644 index 0000000000..e1cd2c1042 --- /dev/null +++ b/src/content/pages/ja/resources/utils.mdx @@ -0,0 +1,22 @@ +--- +title: Express utilities +description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications. +--- + +## Express utility functions + +The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules +for utility functions that may be generally useful. + +| Utility modules | 説明 | +| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. | +| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. | +| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. | +| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. | +| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as \`\`/user/:name\` into a regular expression. | +| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. | +| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. | +| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. | + +For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp). diff --git a/src/content/pages/ja/support.mdx b/src/content/pages/ja/support.mdx new file mode 100644 index 0000000000..077470a060 --- /dev/null +++ b/src/content/pages/ja/support.mdx @@ -0,0 +1,23 @@ +--- +title: バージョンサポート +description: 現在メンテナンスされているバージョンや終了ポリシーを含む、さまざまなExpress.jsバージョンのサポートスケジュールに関する情報をご覧ください。 +--- + +任意のメジャーリリースラインの最新バージョンのみがサポートされています。 + +EOL (終了) _may_ のバージョンは、重大なセキュリティ脆弱性の更新を受け取ります。 しかし、Expressチームは保証を提供しておらず、見つかった問題の修正やリリースを計画していません。 + +| メジャーバージョン | 最小Node.js バージョン | サポート開始日 | サポート終了日 | +| -------------------------------------------------------------- | ---------------------- | -------------- | -------------- | +| [**v5.x**](/5x/api) | 18 | 2024年9月 | **進行中** | +| [**v4.x**](/4x/api) | 0.10.0 | 2014 年 4 月 | **進行中** | +| [**v3.x**](/3x/api) | 0.8.0 | 2012年10月 | 2015 年 7 月 | +| [**v2.x**](https://github.com/expressjs/expressjs.com/tree/2x) | 0.4.1 | 2011 年 3 月 | 2012 年 7 月 | +| **v1.x** | 0.2.0 | 2010年12月 | 2011 年 3 月 | +| **v0.14.x** | 0.1.98 | 2010年12月 | 2010年12月 | + +## 商用サポートオプション + +サポートされているバージョンの Express にアップデートできない場合は、以下のいずれかのパートナーにお問い合わせください: + +- [HeroDevs Never-Ending Support](https://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/src/content/pages/ko/advanced/best-practice-performance.mdx b/src/content/pages/ko/advanced/best-practice-performance.mdx new file mode 100644 index 0000000000..797743e6ad --- /dev/null +++ b/src/content/pages/ko/advanced/best-practice-performance.mdx @@ -0,0 +1,333 @@ +--- +title: 'Production best practices: performance and reliability' +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. +--- + +This article discusses performance and reliability best practices for Express applications deployed to production. + +This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: [things to do in your code](#things-to-do-in-your-code) (the dev part), and [things to do in your environment / setup](#things-to-do-in-your-environment--setup) (the ops part). + +## Things to do in your code + +Here are some things you can do in your code to improve your application's performance. + +### Use gzip compression + +Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. For example: + +```cjs title="index.cjs" +const compression = require('compression'); +const express = require('express'); +const app = express(); + +app.use(compression()); +``` + +```mjs title="index.mjs" +import compression from 'compression'; +import express from 'express'; + +const app = express(); + +app.use(compression()); +``` + +For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) in the Nginx documentation. + +### Don't use synchronous functions + +Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production. + +Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup. + +You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli.html#--trace-sync-io) for more information. + +### Do logging correctly + +In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console.html#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. + +#### For debugging + +If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you? + +#### For app activity + +If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available. + +### Handle exceptions properly + +Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly. + +To ensure you handle all exceptions, use the following techniques: + +- [Use try-catch](#use-try-catch) +- [Use promises](#use-promises) + +Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain. + +For more on the fundamentals of error handling, see: + +- [Error Handling in Node.js](https://web.archive.org/web/20210619211351/https://www.joyent.com/node-js/production/design/errors) + +#### Use try-catch + +Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below. + +Here is an example of using try-catch to handle a potential process-crashing exception. +This middleware function accepts a query field parameter named "params" that is a JSON object. + +```js +app.get('/search', (req, res) => { + // Simulating async operation + setImmediate(() => { + const jsonStr = req.query.params; + try { + const jsonObj = JSON.parse(jsonStr); + res.send('Success'); + } catch (e) { + res.status(400).send('Invalid JSON string'); + } + }); +}); +``` + +However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions. + +#### Use promises + +When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)` + +```js +app.get('/', async (req, res, next) => { + const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error. + + res.send(data); +}); + +app.use((err, req, res, next) => { + res.status(err.status ?? 500).send({ error: err.message }); +}); +``` + +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: + +```js +app.use(async (req, res, next) => { + req.locals.user = await getUser(req); + + next(); // This will be called if the promise does not throw an error. +}); +``` + +Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware. + +#### What not to do + +One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable. + +Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process.html#event-uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error. + +We also don't recommend using [domains](https://nodejs.org/api/domain.html). It generally doesn't solve the problem and is a deprecated module. + +### Use worker threads for CPU-intensive tasks + +Node.js runs your JavaScript on a single thread, so a CPU-intensive operation (such as image processing, parsing or transforming large payloads, or cryptographic operations) can block the event loop and slow down every request your Express app is handling. If your app does CPU-bound work, you can run it in [worker threads](https://nodejs.org/api/worker_threads.html), which execute JavaScript in parallel within the same process, keeping the main thread free to serve requests. + +Each worker thread runs in its own JavaScript engine instance, so the data you pass to it through `workerData` or `postMessage` is copied, not shared. Copying large payloads has a cost of its own, which you can avoid by transferring objects such as `ArrayBuffer`s or by sharing memory explicitly with `SharedArrayBuffer`. Worker threads are not a replacement for [running your app in a cluster](#run-your-app-in-a-cluster), which scales your app across CPU cores by running multiple instances of it in separate processes. + +This example offloads an image-resizing task to a worker, where `resize-worker.js` receives the image via `workerData` and posts the result back when it's done: + +```js +const { Worker } = require('node:worker_threads'); + +app.post('/resize', (req, res, next) => { + const worker = new Worker('./resize-worker.js', { workerData: req.body.image }); + + worker.once('message', (result) => res.send(result)); + worker.once('error', next); +}); +``` + +Note that this example is kept simple for illustration: creating a worker thread is relatively expensive, so [the Node.js documentation recommends using a pool of workers](https://nodejs.org/api/worker_threads.html#worker-threads) instead of spawning a new one for every request. Create a fixed pool of workers at startup and dispatch tasks to them as requests come in, for example with a library like [piscina](https://www.npmjs.com/package/piscina): + +```js +const path = require('node:path'); +const Piscina = require('piscina'); + +const pool = new Piscina({ filename: path.resolve(__dirname, 'resize-worker.js') }); + +app.post('/resize', async (req, res, next) => { + try { + res.send(await pool.run(req.body.image)); + } catch (err) { + next(err); + } +}); +``` + +Here `resize-worker.js` simply exports the function to run in the pool, and piscina takes care of creating the workers, queueing tasks, and reusing threads across requests. + +For more guidance on keeping the event loop responsive, including when offloading work is worth its communication costs, see [Don't Block the Event Loop](https://nodejs.org/learn/asynchronous-work/dont-block-the-event-loop) in the Node.js documentation. + +## Things to do in your environment / setup + +Here are some things you can do in your system environment to improve your app's performance. + +### Set NODE_ENV to "production" + +The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. + +Setting NODE_ENV to "production" makes Express: + +- Cache view templates. +- Cache CSS files generated from CSS extensions. +- Generate less verbose error messages. + +[Tests indicate](https://web.archive.org/web/20250814011110/https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three! + +If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. + +In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here. + +With systemd, use the `Environment` directive in your unit file. For example: + +```sh + +Environment=NODE_ENV=production +``` + +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). + +### Use the latest LTS version of Node.js + +Running your app on a recent Node.js release is one of the easiest ways to improve performance. Each new version of Node.js ships with cumulative improvements to the V8 JavaScript engine and the runtime itself, so the same Express app can handle significantly more requests simply by upgrading. Benchmarks such as NodeSource's [Node.js Performance Report](https://nodesource.com/pages/content-node-performance-report-wb.html) show how much throughput can improve from one Node.js version to the next. For production, use the latest [LTS release](https://nodejs.org/en/about/previous-releases) of Node.js, and keep it up to date as new versions come out. + +### Ensure your app automatically restarts + +In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by: + +- Using a process manager to restart the app (and Node) when it crashes. +- Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager. + +Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart. + +#### Use a process manager + +In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime. + +In addition to restarting your app when it crashes, a process manager can enable you to: + +- Gain insights into runtime performance and resource consumption. +- Modify settings dynamically to improve performance. +- Control clustering (pm2). + +Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management. + +#### Use an init system + +The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd). + +There are two ways to use init systems with your Express app: + +- Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach. +- Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager. + +##### Systemd + +Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system. + +A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `\` for your system and app: + +```sh +[Unit] +Description= + +[Service] +Type=simple +ExecStart=/usr/local/bin/node +WorkingDirectory= + +User=nobody +Group=nogroup + + +Environment=NODE_ENV=production + + +LimitNOFILE=infinity + + +LimitCORE=infinity + +StandardInput=null +StandardOutput=syslog +StandardError=syslog +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +For more information on systemd, see the [systemd reference (man page)](https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html). + +### Run your app in a cluster + +In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. + +![Balancing between application instances using the cluster API](/images/clustering.png) + +IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](https://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers. + +In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork(). + +#### Using Node's cluster module + +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. + +#### Using PM2 + +If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like). + +When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app. + +To enable cluster mode, start your application like so: + +```bash + +$ pm2 start npm --name my-app -i 4 -- start + +$ pm2 start npm --name my-app -i max -- start +``` + +This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start. + +Once running, the application can be scaled like so: + +```bash + +$ pm2 scale my-app +3 + +$ pm2 scale my-app 2 +``` + +For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. + +### Cache request results + +Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly. + +Use a caching server like [Varnish](https://www.varnish.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/c/nginx-caching)) to greatly improve the speed and performance of your app. + +### Use a load balancer + +No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance. + +A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). + +With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/). + +### Use a reverse proxy + +A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things. + +Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/src/content/pages/ko/advanced/best-practice-security.mdx b/src/content/pages/ko/advanced/best-practice-security.mdx index 2b96bbceef..5abff8aa6a 100644 --- a/src/content/pages/ko/advanced/best-practice-security.mdx +++ b/src/content/pages/ko/advanced/best-practice-security.mdx @@ -64,7 +64,7 @@ Here is an example of checking URLs before using `res.redirect` or `res.location ```js app.use((req, res) => { try { - if (new Url(req.query.url).host !== 'example.com') { + if (new URL(req.query.url).host !== 'example.com') { return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`); } } catch (e) { diff --git a/src/content/pages/ko/advanced/healthcheck-graceful-shutdown.mdx b/src/content/pages/ko/advanced/healthcheck-graceful-shutdown.mdx new file mode 100644 index 0000000000..5d7b87ac11 --- /dev/null +++ b/src/content/pages/ko/advanced/healthcheck-graceful-shutdown.mdx @@ -0,0 +1,28 @@ +--- +title: Health Checks and Graceful Shutdown +description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes. +--- + +## Graceful shutdown + +When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit. + +### Example + +```js +const server = app.listen(port); + +process.on('SIGTERM', () => { + debug('SIGTERM signal received: closing HTTP server'); + server.close(() => { + debug('HTTP server closed'); + }); +}); +``` + +## Health checks + +A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes//): + +- `liveness`, that determines when to restart a container. +- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers. diff --git a/src/content/pages/ko/resources/utils.mdx b/src/content/pages/ko/resources/utils.mdx new file mode 100644 index 0000000000..739b352f3e --- /dev/null +++ b/src/content/pages/ko/resources/utils.mdx @@ -0,0 +1,22 @@ +--- +title: Express utilities +description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications. +--- + +## Express utility functions + +The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules +for utility functions that may be generally useful. + +| Utility modules | Description | +| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. | +| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. | +| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. | +| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. | +| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as \`\`/user/:name\` into a regular expression. | +| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. | +| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. | +| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. | + +For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp). diff --git a/src/content/pages/ko/support.mdx b/src/content/pages/ko/support.mdx new file mode 100644 index 0000000000..118dd0dcb2 --- /dev/null +++ b/src/content/pages/ko/support.mdx @@ -0,0 +1,23 @@ +--- +title: Version Support +description: Find information about the support schedule for different Express.js versions, including which versions are currently maintained and end-of-life policies. +--- + +Only the latest version of any given major release line is supported. + +Versions that are EOL (end-of-life) _may_ receive updates for critical security vulnerabilities, but the Express team offers no guarantee and does not plan to address or release fixes for any issues found. + +| Major Version | Minimum Node.js Version | Support Start Date | Support End Date | +| -------------------------------------------------------------- | ----------------------- | ------------------ | ---------------- | +| [**v5.x**](/5x/api) | 18 | September 2024 | **ongoing** | +| [**v4.x**](/4x/api) | 0.10.0 | April 2014 | **ongoing** | +| [**v3.x**](/3x/api) | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**](https://github.com/expressjs/expressjs.com/tree/2x) | 0.4.1 | March 2011 | July 2012 | +| **v1.x** | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x** | 0.1.98 | December 2010 | December 2010 | + +## Commercial Support Options + +If you are unable to update to a supported version of Express, please contact one of our partners to receive security updates: + +- [HeroDevs Never-Ending Support](https://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/src/content/pages/pt-br/advanced/best-practice-performance.mdx b/src/content/pages/pt-br/advanced/best-practice-performance.mdx new file mode 100644 index 0000000000..94c90a0713 --- /dev/null +++ b/src/content/pages/pt-br/advanced/best-practice-performance.mdx @@ -0,0 +1,333 @@ +--- +title: 'Production best practices: performance and reliability' +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. +--- + +This article discusses performance and reliability best practices for Express applications deployed to production. + +This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: [things to do in your code](#things-to-do-in-your-code) (the dev part), and [things to do in your environment / setup](#things-to-do-in-your-environment--setup) (the ops part). + +## Things to do in your code + +Here are some things you can do in your code to improve your application's performance. + +### Use gzip compression + +Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. Por exemplo: + +```cjs title="index.cjs" +const compression = require('compression'); +const express = require('express'); +const app = express(); + +app.use(compression()); +``` + +```mjs title="index.mjs" +import compression from 'compression'; +import express from 'express'; + +const app = express(); + +app.use(compression()); +``` + +For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) in the Nginx documentation. + +### Don't use synchronous functions + +Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production. + +Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup. + +You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli.html#--trace-sync-io) for more information. + +### Do logging correctly + +In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console.html#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. + +#### For debugging + +If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you? + +#### For app activity + +If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available. + +### Handle exceptions properly + +Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly. + +To ensure you handle all exceptions, use the following techniques: + +- [Use try-catch](#use-try-catch) +- [Use promises](#use-promises) + +Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain. + +For more on the fundamentals of error handling, see: + +- [Error Handling in Node.js](https://web.archive.org/web/20210619211351/https://www.joyent.com/node-js/production/design/errors) + +#### Use try-catch + +Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below. + +Here is an example of using try-catch to handle a potential process-crashing exception. +This middleware function accepts a query field parameter named "params" that is a JSON object. + +```js +app.get('/search', (req, res) => { + // Simulating async operation + setImmediate(() => { + const jsonStr = req.query.params; + try { + const jsonObj = JSON.parse(jsonStr); + res.send('Success'); + } catch (e) { + res.status(400).send('Invalid JSON string'); + } + }); +}); +``` + +However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions. + +#### Use promises + +When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)` + +```js +app.get('/', async (req, res, next) => { + const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error. + + res.send(data); +}); + +app.use((err, req, res, next) => { + res.status(err.status ?? 500).send({ error: err.message }); +}); +``` + +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: + +```js +app.use(async (req, res, next) => { + req.locals.user = await getUser(req); + + next(); // This will be called if the promise does not throw an error. +}); +``` + +Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware. + +#### What not to do + +One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable. + +Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process.html#event-uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error. + +We also don't recommend using [domains](https://nodejs.org/api/domain.html). It generally doesn't solve the problem and is a deprecated module. + +### Use worker threads for CPU-intensive tasks + +Node.js runs your JavaScript on a single thread, so a CPU-intensive operation (such as image processing, parsing or transforming large payloads, or cryptographic operations) can block the event loop and slow down every request your Express app is handling. If your app does CPU-bound work, you can run it in [worker threads](https://nodejs.org/api/worker_threads.html), which execute JavaScript in parallel within the same process, keeping the main thread free to serve requests. + +Each worker thread runs in its own JavaScript engine instance, so the data you pass to it through `workerData` or `postMessage` is copied, not shared. Copying large payloads has a cost of its own, which you can avoid by transferring objects such as `ArrayBuffer`s or by sharing memory explicitly with `SharedArrayBuffer`. Worker threads are not a replacement for [running your app in a cluster](#run-your-app-in-a-cluster), which scales your app across CPU cores by running multiple instances of it in separate processes. + +This example offloads an image-resizing task to a worker, where `resize-worker.js` receives the image via `workerData` and posts the result back when it's done: + +```js +const { Worker } = require('node:worker_threads'); + +app.post('/resize', (req, res, next) => { + const worker = new Worker('./resize-worker.js', { workerData: req.body.image }); + + worker.once('message', (result) => res.send(result)); + worker.once('error', next); +}); +``` + +Note that this example is kept simple for illustration: creating a worker thread is relatively expensive, so [the Node.js documentation recommends using a pool of workers](https://nodejs.org/api/worker_threads.html#worker-threads) instead of spawning a new one for every request. Create a fixed pool of workers at startup and dispatch tasks to them as requests come in, for example with a library like [piscina](https://www.npmjs.com/package/piscina): + +```js +const path = require('node:path'); +const Piscina = require('piscina'); + +const pool = new Piscina({ filename: path.resolve(__dirname, 'resize-worker.js') }); + +app.post('/resize', async (req, res, next) => { + try { + res.send(await pool.run(req.body.image)); + } catch (err) { + next(err); + } +}); +``` + +Here `resize-worker.js` simply exports the function to run in the pool, and piscina takes care of creating the workers, queueing tasks, and reusing threads across requests. + +For more guidance on keeping the event loop responsive, including when offloading work is worth its communication costs, see [Don't Block the Event Loop](https://nodejs.org/learn/asynchronous-work/dont-block-the-event-loop) in the Node.js documentation. + +## Things to do in your environment / setup + +Here are some things you can do in your system environment to improve your app's performance. + +### Set NODE_ENV to "production" + +The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. + +Setting NODE_ENV to "production" makes Express: + +- Cache view templates. +- Cache CSS files generated from CSS extensions. +- Generate less verbose error messages. + +[Tests indicate](https://web.archive.org/web/20250814011110/https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three! + +If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. + +In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here. + +With systemd, use the `Environment` directive in your unit file. Por exemplo: + +```sh + +Environment=NODE_ENV=production +``` + +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). + +### Use the latest LTS version of Node.js + +Running your app on a recent Node.js release is one of the easiest ways to improve performance. Each new version of Node.js ships with cumulative improvements to the V8 JavaScript engine and the runtime itself, so the same Express app can handle significantly more requests simply by upgrading. Benchmarks such as NodeSource's [Node.js Performance Report](https://nodesource.com/pages/content-node-performance-report-wb.html) show how much throughput can improve from one Node.js version to the next. For production, use the latest [LTS release](https://nodejs.org/en/about/previous-releases) of Node.js, and keep it up to date as new versions come out. + +### Ensure your app automatically restarts + +In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by: + +- Using a process manager to restart the app (and Node) when it crashes. +- Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager. + +Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart. + +#### Use a process manager + +In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime. + +In addition to restarting your app when it crashes, a process manager can enable you to: + +- Gain insights into runtime performance and resource consumption. +- Modify settings dynamically to improve performance. +- Control clustering (pm2). + +Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management. + +#### Use an init system + +The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd). + +There are two ways to use init systems with your Express app: + +- Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach. +- Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager. + +##### Systemd + +Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system. + +A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `\` for your system and app: + +```sh +[Unit] +Description= + +[Service] +Type=simple +ExecStart=/usr/local/bin/node +WorkingDirectory= + +User=nobody +Group=nogroup + + +Environment=NODE_ENV=production + + +LimitNOFILE=infinity + + +LimitCORE=infinity + +StandardInput=null +StandardOutput=syslog +StandardError=syslog +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +For more information on systemd, see the [systemd reference (man page)](https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html). + +### Run your app in a cluster + +In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. + +![Balancing between application instances using the cluster API](/images/clustering.png) + +IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](https://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers. + +In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork(). + +#### Using Node's cluster module + +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. + +#### Using PM2 + +If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like). + +When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app. + +To enable cluster mode, start your application like so: + +```bash + +$ pm2 start npm --name my-app -i 4 -- start + +$ pm2 start npm --name my-app -i max -- start +``` + +This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start. + +Once running, the application can be scaled like so: + +```bash + +$ pm2 scale my-app +3 + +$ pm2 scale my-app 2 +``` + +For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. + +### Cache request results + +Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly. + +Use a caching server like [Varnish](https://www.varnish.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/c/nginx-caching)) to greatly improve the speed and performance of your app. + +### Use a load balancer + +No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance. + +A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). + +With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/). + +### Use a reverse proxy + +A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things. + +Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/src/content/pages/pt-br/advanced/best-practice-security.mdx b/src/content/pages/pt-br/advanced/best-practice-security.mdx index b821796093..a6a4f93f44 100644 --- a/src/content/pages/pt-br/advanced/best-practice-security.mdx +++ b/src/content/pages/pt-br/advanced/best-practice-security.mdx @@ -64,7 +64,7 @@ Aqui está um exemplo de verificar URLs antes de usar `res.redirect` ou `res.loc ```js app.use((req, res) => { try { - if (new Url(req.query.url).host !== 'example.com') { + if (new URL(req.query.url).host !== 'example.com') { return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`); } } catch (e) { diff --git a/src/content/pages/pt-br/advanced/healthcheck-graceful-shutdown.mdx b/src/content/pages/pt-br/advanced/healthcheck-graceful-shutdown.mdx new file mode 100644 index 0000000000..c9d714aba5 --- /dev/null +++ b/src/content/pages/pt-br/advanced/healthcheck-graceful-shutdown.mdx @@ -0,0 +1,28 @@ +--- +title: Health Checks and Graceful Shutdown +description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes. +--- + +## Graceful shutdown + +When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit. + +### Exemplo + +```js +const server = app.listen(port); + +process.on('SIGTERM', () => { + debug('SIGTERM signal received: closing HTTP server'); + server.close(() => { + debug('HTTP server closed'); + }); +}); +``` + +## Health checks + +A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes//): + +- `liveness`, that determines when to restart a container. +- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers. diff --git a/src/content/pages/pt-br/resources/utils.mdx b/src/content/pages/pt-br/resources/utils.mdx new file mode 100644 index 0000000000..6726758fcd --- /dev/null +++ b/src/content/pages/pt-br/resources/utils.mdx @@ -0,0 +1,22 @@ +--- +title: Express utilities +description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications. +--- + +## Express utility functions + +The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules +for utility functions that may be generally useful. + +| Utility modules | Descrição: | +| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. | +| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. | +| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. | +| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. | +| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as \`\`/user/:name\` into a regular expression. | +| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. | +| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. | +| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. | + +For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp). diff --git a/src/content/pages/pt-br/support.mdx b/src/content/pages/pt-br/support.mdx new file mode 100644 index 0000000000..22d8564c69 --- /dev/null +++ b/src/content/pages/pt-br/support.mdx @@ -0,0 +1,23 @@ +--- +title: Suporte à Versão +description: Encontre informações sobre o cronograma de suporte para diferentes versões do Express.js, incluindo quais versões são atualmente mantidas e políticas em fim de vida. +--- + +Somente a versão mais recente de qualquer linha de lançamento principal é suportada. + +Versões que são EOL (fim de vida) _pode_ receber atualizações de vulnerabilidades de segurança críticas, mas a equipe Express não oferece garantia e não planeja endereçar ou liberar correções para quaisquer problemas encontrados. + +| Major Version | Versão mínima do Node.js | Support Start Date | Support End Date | +| -------------------------------------------------------------- | ------------------------ | ------------------ | ---------------- | +| [**v5.x**](/5x/api) | 18 | Setembro de 2024 | **em andamento** | +| [**v4.x**](/4x/api) | 0.10.0 | Abril de 2014 | **em andamento** | +| [**v3.x**](/3x/api) | 0.8.0 | Outubro de 2012 | Julho de 2015 | +| [**v2.x**](https://github.com/expressjs/expressjs.com/tree/2x) | 0.4.1 | Março de 2011 | Julho de 2012 | +| **v1.x** | 0.2.0 | Dezembro de 2010 | Março de 2011 | +| **v0.14.x** | 0.1.98 | Dezembro de 2010 | Dezembro de 2010 | + +## Opções de Suporte Comercial + +Se você não puder atualizar para uma versão suportada do Express, entre em contato com um de nossos parceiros para receber atualizações de segurança: + +- [HeroDevs Never-Ending Support](https://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/src/content/pages/zh-cn/advanced/best-practice-performance.mdx b/src/content/pages/zh-cn/advanced/best-practice-performance.mdx new file mode 100644 index 0000000000..e45057c5c3 --- /dev/null +++ b/src/content/pages/zh-cn/advanced/best-practice-performance.mdx @@ -0,0 +1,333 @@ +--- +title: 生产环境最佳实践:性能与可靠性 +description: 探寻生产环境下Express应用在性能与可靠性方面的最佳实践,涵盖实现最优性能所需的代码优化与环境配置。 +--- + +本文介绍部署至生产环境的Express应用在性能和可靠性方面的最佳实践。 + +该主题明显属于“开发运维(DevOps)”范畴,兼顾传统开发与运维两大领域。 Accordingly, the information is divided into two parts: [things to do in your code](#things-to-do-in-your-code) (the dev part), and [things to do in your environment / setup](#things-to-do-in-your-environment--setup) (the ops part). + +## 代码层面的优化事项 + +你可以在代码中执行以下操作来提升应用性能: + +### 使用gzip压缩 + +Gzip压缩可大幅减小响应体大小,从而提升Web应用的运行速度。 在Express应用中使用 [compression](https://www.npmjs.com/package/compression) 中间件实现gzip压缩。 举个例子: + +```cjs title="index.cjs" +const compression = require('compression'); +const express = require('express'); +const app = express(); + +app.use(compression()); +``` + +```mjs title="index.mjs" +import compression from 'compression'; +import express from 'express'; + +const app = express(); + +app.use(compression()); +``` + +对于生产环境中的高流量网站,实施压缩的最佳方式是在反向代理层实现(参见[使用反向代理](#use-a-reverse-proxy))。 这种情况下,你无需使用压缩中间件。 For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) in the Nginx documentation. + +### 不要使用同步函数 + +同步函数和方法会阻塞执行进程,直至其执行完毕并返回结果。 单次调用同步函数可能仅需几微秒或几毫秒即可返回,但在高流量网站中,这些调用会累积起来,降低应用性能。 在生产环境中应避免使用同步函数。 + +尽管Node.js及许多模块都提供了函数的同步和异步版本,但在生产环境中务必使用异步版本。 唯一可以合理使用同步函数的场景是应用初始启动阶段。 + +你可以使用 `--trace-sync-io` 命令行标志,在应用每次调用同步API时输出警告信息与堆栈跟踪。 当然,你不应该在生产环境中使用该标志,而应在代码准备部署到生产环境前使用它来排查问题。 See the [node command-line options documentation](https://nodejs.org/api/cli.html#--trace-sync-io) for more information. + +### 正确进行日志记录 + +通常,应用程序记录日志有两个目的:调试,以及记录应用运行活动(除此之外的所有场景基本都归为此类)。 在开发过程中,使用 `console.log()` 或 `console.error()` 将日志信息打印到终端是常见做法。 But [these functions are synchronous](https://nodejs.org/api/console.html#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. + +#### 用于调试 + +如果你的日志记录目的是调试,那么请使用专门的调试模块(例如 [debug](https://www.npmjs.com/package/debug)),而非使用 `console.log()`。 该模块允许你使用 DEBUG 环境变量来控制将哪些调试信息发送到 `console.error()`(如果存在的话)。 若要保持应用程序完全异步,你仍然需要将 `console.error()` 的输出通过管道传输到另一个程序。 但话说回来,你并不会真的在生产环境中进行调试,对吧? + +#### 用于应用运行活动记录 + +如果你的目的是记录应用运行活动(例如追踪流量或API调用),请不要使用 `console.log()`,而是使用如 [Pino](https://www.npmjs.com/package/pino) 这样的日志库,它是目前速度最快、效率最高的选择。 + +### 正确处理异常 + +Node 应用在遇到未捕获异常时会崩溃。 不处理异常并采取相应措施会导致你的 Express 应用崩溃并下线。 如果你遵循下文 [确保应用自动重启](#ensure-your-app-automatically-restarts) 中的建议,那么你的应用将能从崩溃中恢复。 幸运的是,Express 应用的启动耗时通常很短。 尽管如此,你首先需要避免应用崩溃,而要做到这一点,就必须正确处理异常。 + +为确保处理所有异常,请使用以下方法: + +- [Use try-catch](#use-try-catch) +- [Use promises](#use-promises) + +在深入探讨这些主题之前,你应该对 Node/Express 错误处理有基本的了解:使用错误优先回调函数,以及在中间件中传递错误。 Node 使用**错误优先回调**约定从异步函数中返回错误,回调函数的第一个参数是错误对象,后续参数为结果数据。 若不存在错误,请将 `null` 作为第一个参数传递。 回调函数必须相应地遵循错误优先回调约定,才能有效处理错误。 而在 Express 中,最佳实践是使用 `next()` 函数沿着中间件链传递错误。 + +如需了解错误处理基础的更多内容,请参阅: + +- [Error Handling in Node.js](https://web.archive.org/web/20210619211351/https://www.joyent.com/node-js/production/design/errors) + +#### 使用 try-catch + +`try-catch` 是一种 JavaScript 语言结构,可用于捕获同步代码中的异常。 例如,可使用 `try-catch` 处理 JSON 解析错误,如下所示。 + +以下是一个使用 `try-catch` 处理可能导致进程崩溃的异常的示例。 +该中间件函数接收一个名为 `params` 的查询字段参数,该参数是一个 JSON 对象。 + +```js +app.get('/search', (req, res) => { + // Simulating async operation + setImmediate(() => { + const jsonStr = req.query.params; + try { + const jsonObj = JSON.parse(jsonStr); + res.send('Success'); + } catch (e) { + res.status(400).send('Invalid JSON string'); + } + }); +}); +``` + +但是,`try-catch` 仅适用于同步代码。 由于 Node 平台主要是异步的(尤其是在生产环境中),`try-catch` 无法捕获大量异常。 + +#### 使用 Promise + +当在 `async` 函数中抛出错误,或在 `async` 函数内等待(await)一个已被拒绝的 Promise 时,这些错误会被传递给错误处理程序,效果等同于调用 `next(err)`。 + +```js +app.get('/', async (req, res, next) => { + const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error. + + res.send(data); +}); + +app.use((err, req, res, next) => { + res.status(err.status ?? 500).send({ error: err.message }); +}); +``` + +此外,你可以将异步函数用于中间件,若 Promise 失败,路由器会自动处理错误,例如: + +```js +app.use(async (req, res, next) => { + req.locals.user = await getUser(req); + + next(); // This will be called if the promise does not throw an error. +}); +``` + +最佳实践是尽可能在错误发生的就近位置处理错误。 因此,虽然这类错误现在可由路由器处理,但最佳做法是在中间件中捕获并处理错误,而不依赖独立的错误处理中间件。 + +#### 不要执行的操作 + +你**不应**执行的操作之一是监听 `uncaughtException` 事件,该事件会在异常一直冒泡回到事件循环时触发。 为 `uncaughtException` 添加事件监听器会改变进程遇到异常时的默认行为;即便发生异常,进程仍会继续运行。 这听起来似乎是防止应用崩溃的好方法,但在发生未捕获异常后继续运行应用是一种危险的做法,**不推荐使用**,因为此时进程的状态会变得不可靠且不可预测。 + +Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process.html#event-uncaughtexception). 因此,监听 `uncaughtException` 是一种不可取的做法。 这也是我们推荐使用多进程和进程管理工具的原因:崩溃后重启通常是从错误中恢复的最可靠方式。 + +We also don't recommend using [domains](https://nodejs.org/api/domain.html). 该模块通常无法解决问题,且已被废弃。 + +### Use worker threads for CPU-intensive tasks + +Node.js runs your JavaScript on a single thread, so a CPU-intensive operation (such as image processing, parsing or transforming large payloads, or cryptographic operations) can block the event loop and slow down every request your Express app is handling. If your app does CPU-bound work, you can run it in [worker threads](https://nodejs.org/api/worker_threads.html), which execute JavaScript in parallel within the same process, keeping the main thread free to serve requests. + +Each worker thread runs in its own JavaScript engine instance, so the data you pass to it through `workerData` or `postMessage` is copied, not shared. Copying large payloads has a cost of its own, which you can avoid by transferring objects such as `ArrayBuffer`s or by sharing memory explicitly with `SharedArrayBuffer`. Worker threads are not a replacement for [running your app in a cluster](#run-your-app-in-a-cluster), which scales your app across CPU cores by running multiple instances of it in separate processes. + +This example offloads an image-resizing task to a worker, where `resize-worker.js` receives the image via `workerData` and posts the result back when it's done: + +```js +const { Worker } = require('node:worker_threads'); + +app.post('/resize', (req, res, next) => { + const worker = new Worker('./resize-worker.js', { workerData: req.body.image }); + + worker.once('message', (result) => res.send(result)); + worker.once('error', next); +}); +``` + +Note that this example is kept simple for illustration: creating a worker thread is relatively expensive, so [the Node.js documentation recommends using a pool of workers](https://nodejs.org/api/worker_threads.html#worker-threads) instead of spawning a new one for every request. Create a fixed pool of workers at startup and dispatch tasks to them as requests come in, for example with a library like [piscina](https://www.npmjs.com/package/piscina): + +```js +const path = require('node:path'); +const Piscina = require('piscina'); + +const pool = new Piscina({ filename: path.resolve(__dirname, 'resize-worker.js') }); + +app.post('/resize', async (req, res, next) => { + try { + res.send(await pool.run(req.body.image)); + } catch (err) { + next(err); + } +}); +``` + +Here `resize-worker.js` simply exports the function to run in the pool, and piscina takes care of creating the workers, queueing tasks, and reusing threads across requests. + +For more guidance on keeping the event loop responsive, including when offloading work is worth its communication costs, see [Don't Block the Event Loop](https://nodejs.org/learn/asynchronous-work/dont-block-the-event-loop) in the Node.js documentation. + +## 环境/安装设置注意事项 + +你可以在系统环境中进行以下操作来提升应用性能: + +### 将 `NODE_ENV` 设置为 `"production"` + +`NODE_ENV` 环境变量用于指定应用的运行环境(通常为开发环境或生产环境)。 提升性能最简单的操作之一就是将 `NODE_ENV` 设为 `production`。 + +将 `NODE_ENV` 设置为 `"production"` 会使 Express: + +- 缓存视图模板。 +- 缓存由 CSS 扩展生成的 CSS 文件。 +- 生成更简洁的错误提示信息。 + +[Tests indicate](https://web.archive.org/web/20250814011110/https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three! + +若需要编写针对特定环境的代码,可通过 `process.env.NODE_ENV` 检查 `NODE_ENV` 的值。 请注意,检查任何环境变量的值都会产生性能损耗,因此应谨慎使用。 + +在开发环境中,你通常在交互式 shell 中设置环境变量,例如使用 `export` 命令或 `.bash_profile` 文件。 但通常情况下,你不应该在生产服务器上这样做;相反,应使用操作系统的初始化系统(systemd)。 下一节将详细介绍如何使用初始化系统,但由于设置 `NODE_ENV` 对性能至关重要(且操作简便),因此在此单独强调。 + +使用 systemd 时,在单元文件中使用 `Environment` 指令。 举个例子: + +```sh + +Environment=NODE_ENV=production +``` + +如需了解更多信息,参阅[在 systemd 单元中使用环境变量](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/)。 + +### Use the latest LTS version of Node.js + +Running your app on a recent Node.js release is one of the easiest ways to improve performance. Each new version of Node.js ships with cumulative improvements to the V8 JavaScript engine and the runtime itself, so the same Express app can handle significantly more requests simply by upgrading. Benchmarks such as NodeSource's [Node.js Performance Report](https://nodesource.com/pages/content-node-performance-report-wb.html) show how much throughput can improve from one Node.js version to the next. For production, use the latest [LTS release](https://nodejs.org/en/about/previous-releases) of Node.js, and keep it up to date as new versions come out. + +### 确保应用自动重启 + +在生产环境中,你绝不希望应用程序出现离线状态。 这意味着你需要确保**无论应用崩溃还是服务器本身崩溃,应用都能自动重启**。 尽管你希望这两种情况都不会发生,但在实际场景中,你必须通过以下方式应对这两种情况: + +- 使用进程管理器在应用(及 Node)崩溃时将其重启。 +- 借助操作系统自带的初始化系统,在操作系统异常后重启进程管理器。 你也可以不使用进程管理器,直接使用初始化系统。 + +Node 应用在遇到未捕获异常时会崩溃。 首要任务是保证应用经过充分测试、妥善处理所有异常(详情参见[合理处理异常](#handle-exceptions-properly))。 但作为故障安全保障,需部署一套机制,确保应用一旦崩溃便能**自动重启**。 + +#### 使用进程管理器 + +在开发环境中,你通常只需通过命令行(例如执行 `node server.js`)来启动应用。 但在生产环境中采用这种启动方式极易引发故障。 倘若应用崩溃,服务就会中断,需要手动重启才能恢复。 如需应用程序意外崩溃后自动重启,请使用进程管理器。 进程管理器是应用的“容器”,可简化部署流程、保障高可用,并支持在运行阶段管理应用。 + +除了在应用崩溃时重启应用外,进程管理器还可实现以下功能: + +- 查看运行时性能与资源占用情况。 +- 动态修改配置以优化性能。 +- 控制集群(pm2)。 + +以往,使用 [PM2](https://github.com/Unitech/pm2) 这类 Node.js 进程管理器十分普遍。 如需使用,请查阅其官方文档。 不过我们建议采用系统初始化程序进行进程管理。 + +#### ### 使用系统初始化服务 + +保障可靠性的下一步是确保服务器重启时应用也能自动重启。 服务器仍可能因各类故障宕机。 如需在服务器崩溃后重启应用,请使用操作系统内置的初始化系统。 如今主流的初始化系统为 [systemd](https://wiki.debian.org/systemd)。 + +在 Express 应用中使用初始化系统有两种方式: + +- 在进程管理器中运行应用,并通过初始化系统将该进程管理器安装为系统服务。 应用崩溃时进程管理器会重启应用,操作系统重启时初始化系统会重启进程管理器。 该方案为推荐方案。 +- 直接通过初始化系统运行你的应用(以及 Node)。 该方式相对简便,但无法获得使用进程管理器带来的额外优势。 + +##### Systemd + +systemd 是一款 Linux 系统与服务管理器。 多数主流 Linux 发行版已将 systemd 设为默认初始化系统。 + +systemd 服务配置文件被称为**单元文件**,文件名以 `.service` 结尾。 以下是一个直接管理 Node 应用的单元文件示例。 Replace the values enclosed in `\` for your system and app: + +```sh +[Unit] +Description= + +[Service] +Type=simple +ExecStart=/usr/local/bin/node +WorkingDirectory= + +User=nobody +Group=nogroup + + +Environment=NODE_ENV=production + + +LimitNOFILE=infinity + + +LimitCORE=infinity + +StandardInput=null +StandardOutput=syslog +StandardError=syslog +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +For more information on systemd, see the [systemd reference (man page)](https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html). + +### 以集群模式运行应用 + +在多核系统中,通过启动进程集群可以将 Node 应用的性能提升数倍。 集群会运行应用的多个实例,理想情况下每个 CPU 核心运行一个实例,从而在各实例之间分配负载与任务。 + +![Balancing between application instances using the cluster API](/images/clustering.png) + +重要提示:由于应用实例以独立进程运行,它们不共享相同的内存空间。 也就是说,对象仅作用于应用的每个独立实例。 因此,你无法在应用代码中维护状态。 不过你可以使用 [Redis](http://redis.io/) 这类内存型数据存储来存储会话相关数据与状态。 该注意事项基本适用于所有形式的水平扩展,无论是多进程集群还是多物理服务器部署。 + +在集群化应用中,工作进程可单独崩溃而不会影响其余进程。 除性能优势外,故障隔离是采用应用进程集群部署的另一原因。 每当工作进程崩溃时,务必记录该事件,并使用 cluster.fork() 生成新进程。 + +#### Using Node's cluster module + +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). 该模块可让主进程创建多个工作进程,并将接入的连接分发至各个工作进程。 + +#### 使用 PM2 + +如果使用 PM2 部署应用,**无需**修改应用代码即可使用集群功能。 你应当首先确保[应用为无状态应用](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps),即不在进程内存储本地数据(例如会话、WebSocket 连接等数据)。 + +使用 PM2 运行应用程序时,你可以启用**集群模式**,以指定数量的实例(例如与机器上可用 CPU 数量匹配)集群化运行应用。 你可以使用 `pm2` 命令行工具,**无需停止应用**,手动调整集群中的进程数量。 + +要启用集群模式,请按如下方式启动应用程序: + +```bash + +$ pm2 start npm --name my-app -i 4 -- start + +$ pm2 start npm --name my-app -i max -- start +``` + +这也可以在 PM2 进程文件(`ecosystem.config.js` 或类似文件)中进行配置,将 `exec_mode` 设置为 `cluster`,并将 `instances` 设置为要启动的工作进程数量。 + +应用启动后,可按如下方式进行扩容: + +```bash + +$ pm2 scale my-app +3 + +$ pm2 scale my-app 2 +``` + +如需了解更多关于使用 PM2 实现集群部署的相关信息,请参阅 PM2 文档中的[集群模式](https://pm2.keymetrics.io/docs/usage/cluster-mode/)。 + +### 缓存请求结果 + +优化生产环境性能的另一方案是缓存请求返回结果,避免应用重复处理相同请求。 + +Use a caching server like [Varnish](https://www.varnish.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/c/nginx-caching)) to greatly improve the speed and performance of your app. + +### 使用负载均衡器 + +无论应用优化程度多高,单个实例所能承载的负载与流量都存在上限。 应用扩容的一种方案:部署多实例,并通过负载均衡分发流量。 配置负载均衡能够提升应用性能与访问速度,同时让应用实现单实例无法达成的扩容能力。 + +负载均衡器通常是一种反向代理,用于调度多应用实例与多服务器之间的往来流量。 You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). + +使用负载均衡时,你可能需要确保与特定会话 ID 关联的请求能连接到创建该会话的进程。 这被称为**会话亲和性**(_session affinity_),即**粘性会话**(_sticky sessions_),可通过上述建议解决(根据你的应用场景,可采用 Redis 等数据存储来存放会话数据)。 相关说明请参阅[多节点部署](https://socket.io/docs/v4/using-multiple-nodes/)。 + +### # 使用反向代理 + +反向代理部署在 Web 应用前端,除了将请求转发至应用外,还会对请求执行各类辅助操作。 它可处理错误页面、压缩、缓存、静态资源托管以及负载均衡等多项工作。 + +将无需感知应用状态的任务交由反向代理处理,可释放 Express 专注处理各类应用专属任务。 For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/src/content/pages/zh-cn/advanced/best-practice-security.mdx b/src/content/pages/zh-cn/advanced/best-practice-security.mdx index 8fa5c472a9..b5fb1485da 100644 --- a/src/content/pages/zh-cn/advanced/best-practice-security.mdx +++ b/src/content/pages/zh-cn/advanced/best-practice-security.mdx @@ -63,7 +63,7 @@ Also ensure you are not using any of the vulnerable Express versions listed on t ```js app.use((req, res) => { try { - if (new Url(req.query.url).host !== 'example.com') { + if (new URL(req.query.url).host !== 'example.com') { return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`); } } catch (e) { diff --git a/src/content/pages/zh-cn/advanced/healthcheck-graceful-shutdown.mdx b/src/content/pages/zh-cn/advanced/healthcheck-graceful-shutdown.mdx new file mode 100644 index 0000000000..d7fd3206bd --- /dev/null +++ b/src/content/pages/zh-cn/advanced/healthcheck-graceful-shutdown.mdx @@ -0,0 +1,28 @@ +--- +title: 健康检查与优雅关闭 +description: 学习如何在 Express 应用中实现健康检查和优雅关闭,以提升可靠性、管理部署并与 Kubernetes 等负载均衡器集成。 +--- + +## 优雅关闭 + +部署应用新版本时,必须替换旧版本。 你使用的进程管理器会首先向应用发送 SIGTERM 信号,通知应用即将被终止。 应用收到该信号后,应停止接收新请求、完成所有正在处理的请求,释放已使用的资源(包括数据库连接和文件锁),然后退出。 + +### 示例 + +```js +const server = app.listen(port); + +process.on('SIGTERM', () => { + debug('SIGTERM signal received: closing HTTP server'); + server.close(() => { + debug('HTTP server closed'); + }); +}); +``` + +## 健康检查 + +负载均衡器通过健康检查判定应用实例状态是否正常、能否接收请求。 For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes//): + +- `liveness`(存活检查):用于判断何时重启容器。 +- `readiness`(就绪检查):用于判断容器何时准备就绪并开始接收流量。 Pod 未就绪时,会从服务负载均衡器中被剔除。 diff --git a/src/content/pages/zh-cn/resources/utils.mdx b/src/content/pages/zh-cn/resources/utils.mdx new file mode 100644 index 0000000000..71b3537216 --- /dev/null +++ b/src/content/pages/zh-cn/resources/utils.mdx @@ -0,0 +1,21 @@ +--- +title: Express 实用工具 +description: 探索与 Express.js 和 Node.js 相关的实用工具模块,包括 Cookie 处理、CSRF 防护、URL 解析、路由等工具,以增强你的应用程序功能。 +--- + +## Express 实用函数 + +[pillarjs](https://github.com/pillarjs) GitHub 组织包含许多实用函数模块,这些模块在一般情况下也可能非常有用。 + +| 实用工具模块 | 描述 | +| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | +| [cookies](https://www.npmjs.com/package/cookies) | 获取和设置 HTTP(S) Cookie,可使用 Keygrip 进行签名以防止篡改。 可与 Node.js HTTP 库一起使用,或作为 Express 中间件使用。 | +| [csrf](https://www.npmjs.com/package/csrf) | 包含 CSRF 令牌创建与验证的核心逻辑。 使用该模块创建自定义 CSRF 中间件。 | +| [finalhandler](https://www.npmjs.com/package/finalhandler) | 用于作为 HTTP 请求响应最后一步调用的函数。 | +| [parseurl](https://www.npmjs.com/package/parseurl) | 解析 URL,并支持缓存。 | +| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | 将类似 `/user/:name` 的 Express 风格路径字符串转换为正则表达式。 | +| [resolve-path](https://www.npmjs.com/package/resolve-path) | 将相对路径解析为基于根路径的绝对路径,并进行校验。 | +| [router](https://www.npmjs.com/package/router) | 简单的中间件风格路由器。 | +| [send](https://www.npmjs.com/package/send) | 用于将文件以 HTTP 响应流式传输的库,支持部分响应(Range)、条件 GET 协商以及细粒度事件。 | + +For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp). diff --git a/src/content/pages/zh-cn/support.mdx b/src/content/pages/zh-cn/support.mdx new file mode 100644 index 0000000000..b77967f493 --- /dev/null +++ b/src/content/pages/zh-cn/support.mdx @@ -0,0 +1,23 @@ +--- +title: 版本支持 +description: 了解不同 Express.js 版本的支持计划,包括当前仍受维护的版本以及生命周期终止政策。 +--- + +任何主版本分支仅支持其最新版本。 + +已终止生命周期(end-of-life)的版本**可能**会针对严重安全漏洞发布更新,但 Express 团队不作任何保证,也不计划修复或发布任何已发现问题的补丁。 + +| 主版本号 | 最低 Node.js 版本要求 | 支持开始日期 | 支持结束日期 | +| -------------------------------------------------------------- | --------------------- | -------------- | ------------- | +| [**v5.x**](/5x/api) | 18 | September 2024 | **ongoing** | +| [**v4.x**](/4x/api) | 0.10.0 | April 2014 | **ongoing** | +| [**v3.x**](/3x/api) | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**](https://github.com/expressjs/expressjs.com/tree/2x) | 0.4.1 | March 2011 | July 2012 | +| **v1.x** | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x** | 0.1.98 | December 2010 | December 2010 | + +## 商业支持选项 + +如果你无法升级到受支持的 Express 版本,请联系以下合作伙伴获取安全更新: + +- [HeroDevs Never-Ending Support](https://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/src/content/pages/zh-tw/advanced/best-practice-performance.mdx b/src/content/pages/zh-tw/advanced/best-practice-performance.mdx new file mode 100644 index 0000000000..797743e6ad --- /dev/null +++ b/src/content/pages/zh-tw/advanced/best-practice-performance.mdx @@ -0,0 +1,333 @@ +--- +title: 'Production best practices: performance and reliability' +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. +--- + +This article discusses performance and reliability best practices for Express applications deployed to production. + +This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: [things to do in your code](#things-to-do-in-your-code) (the dev part), and [things to do in your environment / setup](#things-to-do-in-your-environment--setup) (the ops part). + +## Things to do in your code + +Here are some things you can do in your code to improve your application's performance. + +### Use gzip compression + +Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. For example: + +```cjs title="index.cjs" +const compression = require('compression'); +const express = require('express'); +const app = express(); + +app.use(compression()); +``` + +```mjs title="index.mjs" +import compression from 'compression'; +import express from 'express'; + +const app = express(); + +app.use(compression()); +``` + +For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) in the Nginx documentation. + +### Don't use synchronous functions + +Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production. + +Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup. + +You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli.html#--trace-sync-io) for more information. + +### Do logging correctly + +In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console.html#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. + +#### For debugging + +If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you? + +#### For app activity + +If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available. + +### Handle exceptions properly + +Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly. + +To ensure you handle all exceptions, use the following techniques: + +- [Use try-catch](#use-try-catch) +- [Use promises](#use-promises) + +Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain. + +For more on the fundamentals of error handling, see: + +- [Error Handling in Node.js](https://web.archive.org/web/20210619211351/https://www.joyent.com/node-js/production/design/errors) + +#### Use try-catch + +Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below. + +Here is an example of using try-catch to handle a potential process-crashing exception. +This middleware function accepts a query field parameter named "params" that is a JSON object. + +```js +app.get('/search', (req, res) => { + // Simulating async operation + setImmediate(() => { + const jsonStr = req.query.params; + try { + const jsonObj = JSON.parse(jsonStr); + res.send('Success'); + } catch (e) { + res.status(400).send('Invalid JSON string'); + } + }); +}); +``` + +However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions. + +#### Use promises + +When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)` + +```js +app.get('/', async (req, res, next) => { + const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error. + + res.send(data); +}); + +app.use((err, req, res, next) => { + res.status(err.status ?? 500).send({ error: err.message }); +}); +``` + +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: + +```js +app.use(async (req, res, next) => { + req.locals.user = await getUser(req); + + next(); // This will be called if the promise does not throw an error. +}); +``` + +Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware. + +#### What not to do + +One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable. + +Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process.html#event-uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error. + +We also don't recommend using [domains](https://nodejs.org/api/domain.html). It generally doesn't solve the problem and is a deprecated module. + +### Use worker threads for CPU-intensive tasks + +Node.js runs your JavaScript on a single thread, so a CPU-intensive operation (such as image processing, parsing or transforming large payloads, or cryptographic operations) can block the event loop and slow down every request your Express app is handling. If your app does CPU-bound work, you can run it in [worker threads](https://nodejs.org/api/worker_threads.html), which execute JavaScript in parallel within the same process, keeping the main thread free to serve requests. + +Each worker thread runs in its own JavaScript engine instance, so the data you pass to it through `workerData` or `postMessage` is copied, not shared. Copying large payloads has a cost of its own, which you can avoid by transferring objects such as `ArrayBuffer`s or by sharing memory explicitly with `SharedArrayBuffer`. Worker threads are not a replacement for [running your app in a cluster](#run-your-app-in-a-cluster), which scales your app across CPU cores by running multiple instances of it in separate processes. + +This example offloads an image-resizing task to a worker, where `resize-worker.js` receives the image via `workerData` and posts the result back when it's done: + +```js +const { Worker } = require('node:worker_threads'); + +app.post('/resize', (req, res, next) => { + const worker = new Worker('./resize-worker.js', { workerData: req.body.image }); + + worker.once('message', (result) => res.send(result)); + worker.once('error', next); +}); +``` + +Note that this example is kept simple for illustration: creating a worker thread is relatively expensive, so [the Node.js documentation recommends using a pool of workers](https://nodejs.org/api/worker_threads.html#worker-threads) instead of spawning a new one for every request. Create a fixed pool of workers at startup and dispatch tasks to them as requests come in, for example with a library like [piscina](https://www.npmjs.com/package/piscina): + +```js +const path = require('node:path'); +const Piscina = require('piscina'); + +const pool = new Piscina({ filename: path.resolve(__dirname, 'resize-worker.js') }); + +app.post('/resize', async (req, res, next) => { + try { + res.send(await pool.run(req.body.image)); + } catch (err) { + next(err); + } +}); +``` + +Here `resize-worker.js` simply exports the function to run in the pool, and piscina takes care of creating the workers, queueing tasks, and reusing threads across requests. + +For more guidance on keeping the event loop responsive, including when offloading work is worth its communication costs, see [Don't Block the Event Loop](https://nodejs.org/learn/asynchronous-work/dont-block-the-event-loop) in the Node.js documentation. + +## Things to do in your environment / setup + +Here are some things you can do in your system environment to improve your app's performance. + +### Set NODE_ENV to "production" + +The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. + +Setting NODE_ENV to "production" makes Express: + +- Cache view templates. +- Cache CSS files generated from CSS extensions. +- Generate less verbose error messages. + +[Tests indicate](https://web.archive.org/web/20250814011110/https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three! + +If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. + +In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here. + +With systemd, use the `Environment` directive in your unit file. For example: + +```sh + +Environment=NODE_ENV=production +``` + +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). + +### Use the latest LTS version of Node.js + +Running your app on a recent Node.js release is one of the easiest ways to improve performance. Each new version of Node.js ships with cumulative improvements to the V8 JavaScript engine and the runtime itself, so the same Express app can handle significantly more requests simply by upgrading. Benchmarks such as NodeSource's [Node.js Performance Report](https://nodesource.com/pages/content-node-performance-report-wb.html) show how much throughput can improve from one Node.js version to the next. For production, use the latest [LTS release](https://nodejs.org/en/about/previous-releases) of Node.js, and keep it up to date as new versions come out. + +### Ensure your app automatically restarts + +In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by: + +- Using a process manager to restart the app (and Node) when it crashes. +- Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager. + +Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart. + +#### Use a process manager + +In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime. + +In addition to restarting your app when it crashes, a process manager can enable you to: + +- Gain insights into runtime performance and resource consumption. +- Modify settings dynamically to improve performance. +- Control clustering (pm2). + +Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management. + +#### Use an init system + +The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd). + +There are two ways to use init systems with your Express app: + +- Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach. +- Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager. + +##### Systemd + +Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system. + +A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `\` for your system and app: + +```sh +[Unit] +Description= + +[Service] +Type=simple +ExecStart=/usr/local/bin/node +WorkingDirectory= + +User=nobody +Group=nogroup + + +Environment=NODE_ENV=production + + +LimitNOFILE=infinity + + +LimitCORE=infinity + +StandardInput=null +StandardOutput=syslog +StandardError=syslog +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +For more information on systemd, see the [systemd reference (man page)](https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html). + +### Run your app in a cluster + +In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. + +![Balancing between application instances using the cluster API](/images/clustering.png) + +IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](https://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers. + +In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork(). + +#### Using Node's cluster module + +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. + +#### Using PM2 + +If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like). + +When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app. + +To enable cluster mode, start your application like so: + +```bash + +$ pm2 start npm --name my-app -i 4 -- start + +$ pm2 start npm --name my-app -i max -- start +``` + +This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start. + +Once running, the application can be scaled like so: + +```bash + +$ pm2 scale my-app +3 + +$ pm2 scale my-app 2 +``` + +For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. + +### Cache request results + +Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly. + +Use a caching server like [Varnish](https://www.varnish.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/c/nginx-caching)) to greatly improve the speed and performance of your app. + +### Use a load balancer + +No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance. + +A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). + +With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/). + +### Use a reverse proxy + +A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things. + +Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/src/content/pages/zh-tw/advanced/best-practice-security.mdx b/src/content/pages/zh-tw/advanced/best-practice-security.mdx index 2b96bbceef..5abff8aa6a 100644 --- a/src/content/pages/zh-tw/advanced/best-practice-security.mdx +++ b/src/content/pages/zh-tw/advanced/best-practice-security.mdx @@ -64,7 +64,7 @@ Here is an example of checking URLs before using `res.redirect` or `res.location ```js app.use((req, res) => { try { - if (new Url(req.query.url).host !== 'example.com') { + if (new URL(req.query.url).host !== 'example.com') { return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`); } } catch (e) { diff --git a/src/content/pages/zh-tw/advanced/healthcheck-graceful-shutdown.mdx b/src/content/pages/zh-tw/advanced/healthcheck-graceful-shutdown.mdx new file mode 100644 index 0000000000..5d7b87ac11 --- /dev/null +++ b/src/content/pages/zh-tw/advanced/healthcheck-graceful-shutdown.mdx @@ -0,0 +1,28 @@ +--- +title: Health Checks and Graceful Shutdown +description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes. +--- + +## Graceful shutdown + +When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit. + +### Example + +```js +const server = app.listen(port); + +process.on('SIGTERM', () => { + debug('SIGTERM signal received: closing HTTP server'); + server.close(() => { + debug('HTTP server closed'); + }); +}); +``` + +## Health checks + +A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes//): + +- `liveness`, that determines when to restart a container. +- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers. diff --git a/src/content/pages/zh-tw/resources/utils.mdx b/src/content/pages/zh-tw/resources/utils.mdx new file mode 100644 index 0000000000..739b352f3e --- /dev/null +++ b/src/content/pages/zh-tw/resources/utils.mdx @@ -0,0 +1,22 @@ +--- +title: Express utilities +description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications. +--- + +## Express utility functions + +The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules +for utility functions that may be generally useful. + +| Utility modules | Description | +| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. | +| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. | +| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. | +| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. | +| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as \`\`/user/:name\` into a regular expression. | +| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. | +| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. | +| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. | + +For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp). diff --git a/src/content/pages/zh-tw/support.mdx b/src/content/pages/zh-tw/support.mdx new file mode 100644 index 0000000000..118dd0dcb2 --- /dev/null +++ b/src/content/pages/zh-tw/support.mdx @@ -0,0 +1,23 @@ +--- +title: Version Support +description: Find information about the support schedule for different Express.js versions, including which versions are currently maintained and end-of-life policies. +--- + +Only the latest version of any given major release line is supported. + +Versions that are EOL (end-of-life) _may_ receive updates for critical security vulnerabilities, but the Express team offers no guarantee and does not plan to address or release fixes for any issues found. + +| Major Version | Minimum Node.js Version | Support Start Date | Support End Date | +| -------------------------------------------------------------- | ----------------------- | ------------------ | ---------------- | +| [**v5.x**](/5x/api) | 18 | September 2024 | **ongoing** | +| [**v4.x**](/4x/api) | 0.10.0 | April 2014 | **ongoing** | +| [**v3.x**](/3x/api) | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**](https://github.com/expressjs/expressjs.com/tree/2x) | 0.4.1 | March 2011 | July 2012 | +| **v1.x** | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x** | 0.1.98 | December 2010 | December 2010 | + +## Commercial Support Options + +If you are unable to update to a supported version of Express, please contact one of our partners to receive security updates: + +- [HeroDevs Never-Ending Support](https://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page)