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..5a7a4ce019 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. @@ -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/generator.mdx b/src/content/docs/de/4x/starter/generator.mdx index e5ec7fc1e3..28ff2d80dd 100644 --- a/src/content/docs/de/4x/starter/generator.mdx +++ b/src/content/docs/de/4x/starter/generator.mdx @@ -42,7 +42,7 @@ $ express -h -f, --force force on non-empty directory ``` -Zum Beispiel erstellt das Folgende eine Express-App namens _myapp_. Die App wird in einem Ordner namens _myapp_ im aktuellen Arbeitsverzeichnis erstellt und die View Engine wird auf Mops gesetzt: +Zum Beispiel erstellt das Folgende eine Express-App namens _myapp_. Die App wird in einem Ordner namens _myapp_ im aktuellen Arbeitsverzeichnis erstellt und die View Engine wird auf Pug gesetzt: ```bash $ express --view=pug myapp 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..ed23e2de40 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. + ## 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. -| 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). + +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,10 @@ 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 }); -``` +```` 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/generator.mdx b/src/content/docs/de/5x/starter/generator.mdx index e5ec7fc1e3..28ff2d80dd 100644 --- a/src/content/docs/de/5x/starter/generator.mdx +++ b/src/content/docs/de/5x/starter/generator.mdx @@ -42,7 +42,7 @@ $ express -h -f, --force force on non-empty directory ``` -Zum Beispiel erstellt das Folgende eine Express-App namens _myapp_. Die App wird in einem Ordner namens _myapp_ im aktuellen Arbeitsverzeichnis erstellt und die View Engine wird auf Mops gesetzt: +Zum Beispiel erstellt das Folgende eine Express-App namens _myapp_. Die App wird in einem Ordner namens _myapp_ im aktuellen Arbeitsverzeichnis erstellt und die View Engine wird auf Pug gesetzt: ```bash $ express --view=pug myapp 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..068e49857a 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. @@ -383,11 +411,11 @@ app.get('/user/:id', (req: Request, res: Response) => { 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` +- `GET /user/0` → primera ruta llama a `next('route')`, 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. -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: +Más de una función de callback puede manejar una ruta (asegúrese de especificar el objeto `next`). 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. | 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..e247dd6e9b 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. + ## 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'; @@ -353,17 +397,19 @@ app.get('/user/:id', (req: Request, res: Response) => { 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` +- `GET /user/0` → primera ruta llama a `next('route')`, 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.A single callback function can handle a route. For example:```js -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`). ```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: +Más de una función de callback puede manejar una ruta (asegúrese de especificar el objeto `next`). 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. -| 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). + +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,10 @@ 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 }); -``` +```` 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..a20aff385c 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. | 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..f57631f85e 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. + ## 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. -| 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). + +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,10 @@ 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 }); -``` +```` 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..e866936c1a 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. | 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..3abc0ea9d7 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. + ## 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. -| 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). + +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,10 @@ 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 }); -``` +```` 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/behind-proxies.mdx b/src/content/docs/ja/4x/guide/behind-proxies.mdx index 70752e3bee..c9241b65b7 100644 --- a/src/content/docs/ja/4x/guide/behind-proxies.mdx +++ b/src/content/docs/ja/4x/guide/behind-proxies.mdx @@ -5,12 +5,12 @@ description: クライアントの IP アドレスを処理するトラストプ import Alert from '@components/primitives/Alert/Alert.astro'; -リバースプロキシの背後で Express アプリケーションを実行する場合、Express API の中には予想以外の値が返されるものがあります。 これを調整するために `trust proxy` アプリケーションの設定は、Express API のリバースプロキシによって提供された情報を公開するために使用することができます。 最も一般的な問題は、クライアントのIPアドレスを公開するAPIで、リバースプロキシの内部IPアドレスが表示される可能性があります。 これを調整するために `trust proxy` アプリケーションの設定は、Express API のリバースプロキシによって提供された情報を公開するために使用することができます。 最も一般的な問題は、クライアントのIPアドレスを公開するAPIで、リバースプロキシの内部IPアドレスが表示される可能性があります。 +リバースプロキシの背後で Express アプリケーションを実行する場合、Express API の中には予想以外の値が返されるものがあります。 これを調整するために `trust proxy` アプリケーションの設定は、Express API のリバースプロキシによって提供された情報を公開するために使用することができます。 最も一般的な問題は、クライアントのIPアドレスを公開するAPIで、リバースプロキシの内部IPアドレスが表示される可能性があります。これを調整するために `trust proxy` アプリケーションの設定は、Express API のリバースプロキシによって提供された情報を公開するために使用することができます。最も一般的な問題は、クライアントのIPアドレスを公開するAPIで、リバースプロキシの内部IPアドレスが表示される可能性があります。 `trust proxy` の設定では、 -リバースプロキシの正確な設定を理解することが重要です。 この設定はリクエストで提供された値を信頼するためです Express での設定の組み合わせが +リバースプロキシの正確な設定を理解することが重要です。この設定はリクエストで提供された値を信頼するためです Express での設定の組み合わせが リバースプロキシの動作と一致することが重要です。 @@ -25,7 +25,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; `true` の場合、クライアントの IP アドレスは `X-Forwarded-For` ヘッダーの中の一番左のエントリとして理解されます。 -`false` の場合、アプリはクライアントに直接向いていると理解され、クライアントの IP アドレスは `req.socket.remoteAddress` に由来します。 これはデフォルトの設定です。 これはデフォルトの設定です。 +`false` の場合、アプリはクライアントに直接向いていると理解され、クライアントの IP アドレスは `req.socket.remoteAddress` に由来します。 これはデフォルトの設定です。これはデフォルトの設定です。 `true` に設定する場合、信頼されている最後のリバースプロキシが以下のすべての HTTP ヘッダを削除/上書きすることが重要です: `X-Forwarded-For` 。 `X-Forwarded-Host` と `X-Forwarded-Proto` があれば、クライアントが何らかの値を提供できるかもしれません。 @@ -35,7 +35,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; IPアドレス -リバースプロキシとして信頼する IP アドレス、サブネット、または IP アドレスとサブネットの配列。 次のリストに、事前に設定されたサブネット名が表示されます。 次のリストに、事前に設定されたサブネット名が表示されます。 +リバースプロキシとして信頼する IP アドレス、サブネット、または IP アドレスとサブネットの配列。 次のリストに、事前に設定されたサブネット名が表示されます。次のリストに、事前に設定されたサブネット名が表示されます。 - loopback - `127.0.0.1/8`, `::1/128` - linklocal - `169.254.0.0/16`, `fe80::/10` @@ -50,7 +50,7 @@ app.set('trust proxy', 'loopback, linklocal, uniquelocal'); // specify multiple app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); // specify multiple subnets as an array ``` -指定された場合、IPアドレスまたはサブネットはアドレス決定プロセスから除外されます。 アプリケーションサーバーに最も近い信頼できないIPアドレスは、クライアントのIPアドレスとして決定されます。 これは `req.socket.remoteAddress` が信頼されているかどうかをチェックすることで動作します。 その場合、`X-Forwarded-For`内の各アドレスは、最初の信頼されていないアドレスまで右から左にチェックされます。 +指定された場合、IPアドレスまたはサブネットはアドレス決定プロセスから除外されます。 アプリケーションサーバーに最も近い信頼できないIPアドレスは、クライアントのIPアドレスとして決定されます。これは `req.socket.remoteAddress` が信頼されているかどうかをチェックすることで動作します。その場合、`X-Forwarded-For`内の各アドレスは、最初の信頼されていないアドレスまで右から左にチェックされます。 @@ -108,4 +108,4 @@ app.set('trust proxy', (ip: string) => { -`trust proxy` は、 [proxy-addr](https://www.npmjs.com/package/proxy-addr) パッケージを使用して実装されています。 詳細については、そのドキュメントを参照してください。 詳細については、そのドキュメントを参照してください。 +`trust proxy` は、 [proxy-addr](https://www.npmjs.com/package/proxy-addr) パッケージを使用して実装されています。 詳細については、そのドキュメントを参照してください。詳細については、そのドキュメントを参照してください。 diff --git a/src/content/docs/ja/4x/guide/debugging.mdx b/src/content/docs/ja/4x/guide/debugging.mdx index 158b013dd9..0445f75013 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:*` に設定します。 @@ -84,24 +85,121 @@ $ DEBUG=express:* node ./bin/www express:view render "/projects/example/views/index.pug" +1ms ``` -ルータの実装からのみログを見るには、`DEBUG`の値を`express:router`に設定します。 同様に、アプリケーションの実装からのログのみを見るには、`DEBUG`の値を`express:application`などに設定します。 同様に、アプリケーションの実装からのログのみを見るには、`DEBUG`の値を`express:application`などに設定します。 +ルータの実装からのみログを見るには、`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..fc9b4119b3 100644 --- a/src/content/docs/ja/4x/guide/error-handling.mdx +++ b/src/content/docs/ja/4x/guide/error-handling.mdx @@ -18,7 +18,7 @@ Express がルートハンドラと ルートハンドラとミドルウェア 内の同期コードで発生するエラーは追加の作業を必要としません。 同期コードがエラーをスローする場合、Expressは キャッチして処理します。 例: 同期コードがエラーをスローする場合、Expressは -キャッチして処理します。 例: +キャッチして処理します。例: ```js app.get('/', (req, res) => { @@ -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..77849fbf18 100644 --- a/src/content/docs/ja/4x/guide/routing.mdx +++ b/src/content/docs/ja/4x/guide/routing.mdx @@ -14,12 +14,11 @@ 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()` を呼び出して、次のコールバックに -を渡すことが重要です。 -複数のコールバック関数を使用。 コールバック関数に `next` を引数として渡し、関数の本体内で `next()` を呼び出して、次のコールバックに +を渡すことが重要です。複数のコールバック関数を使用。 コールバック関数に `next` を引数として渡し、関数の本体内で `next()` を呼び出して、次のコールバックに を渡すことが重要です。 以下のコードは、非常に基本的なルートの例です。 @@ -88,11 +87,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 +113,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 +241,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 +374,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. +リクエストを処理するために、[ミドルウェア](/guide/using-middleware)のように動作する複数のコールバック関数を指定できます。 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) => { @@ -388,11 +417,11 @@ app.get('/user/:id', (req: Request, res: Response) => { この例では: - `GET /user/5` → 最初のルートで処理 → "User 5" を送信 -- `GET /user/0` → 最初のroute ('route')`を呼び出し、次に一致する `/user/:id\` route (ルート) をスキップします。 +- `GET /user/0` → 最初のルートが `next('route')` を呼び出し、次に一致する `/user/:id` ルートへスキップします。 ルートハンドラは、次の例に示すように、関数、関数の配列、または両方の組み合わせの形式で使用できます。 -単一のコールバック関数はルートを処理できます。 例: 例: +単一のコールバック関数はルートを処理できます。例: ```js app.get('/example/a', (req, res) => { @@ -408,7 +437,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -複数のコールバック関数がルートを処理できます (`next` オブジェクトを指定してください)。 例: 例: +複数のコールバック関数がルートを処理できます (`next` オブジェクトを指定してください)。例: ```js app.get( @@ -478,7 +507,7 @@ const cb2 = function (req: Request, res: Response) { app.get('/example/c', [cb0, cb1, cb2]); ``` -独立した関数と関数の配列の組み合わせは、ルートを処理することができます。 例: 例: +独立した関数と関数の配列の組み合わせは、ルートを処理することができます。 例: 例: 例: ```js const cb0 = function (req, res, next) { @@ -532,25 +561,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 +616,9 @@ app ## express.Router -Use the `express.Router` class to create modular, mountable route handlers. `express.Router` クラスを使用して、モジュール化されたマウント可能なルートハンドラを作成します。 `Router`インスタンスは完全なミドルウェアとルーティングシステムです。そのため、しばしば「ミニアプリ」と呼ばれます。 +`express.Router` クラスを使用して、モジュール化されたマウント可能なルートハンドラを作成します。 `Router`インスタンスは完全なミドルウェアとルーティングシステムです。そのため、しばしば「ミニアプリ」と呼ばれます。 -次の例では、ルータをモジュールとして作成し、ミドルウェア関数をロードします。 いくつかのルートを定義し、メインアプリのパスにルータモジュールをマウントします。 +次の例では、ルータをモジュールとして作成し、ミドルウェア関数をロードします。 いくつかのルートを定義し、メインアプリのパスにルータモジュールをマウントします。Create a router file named `birds.js` in the app directory, with th appディレクトリに`birds.js`という名前のルーターファイルを作成します。以下の内容を使用します。 @@ -683,7 +713,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..a5be1dcda4 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'; @@ -8,18 +8,16 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa _template engine_ を使用すると、アプリケーションで静的なテンプレート ファイルを使用できます。 _template engine_ を使用すると、アプリケーションで静的なテンプレート ファイルを使用できます。 実行時に、テンプレートエンジンはテンプレートファイルの 変数を実際の値に置き換えます。 をクリックして、テンプレートをクライアントに送信する HTML ファイルに変換します。 -このアプローチにより、HTML ページのデザインが容易になります。 -このアプローチにより、HTML ページのデザインが容易になります。 +このアプローチにより、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` ディレクトリです。 +- `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: @@ -27,8 +25,9 @@ To render template files, set the following [application setting properties](/ap Pug のような Express 準拠のテンプレートエンジンは、 `__express(filePath, options, callback)` という名前の関数、 `res.render()` がテンプレートコードのレンダリングを呼び出す をエクスポートします。 -一部のテンプレートエンジンはこの規約に従っていません。 一部のテンプレートエンジンはこの規約に従っていません。 [@ladjs/integrate](https://www.npmjs.com/package/@ladjs/consolidate) +一部のテンプレートエンジンはこの規約に従っていません。一部のテンプレートエンジンはこの規約に従っていません。 [@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..d1944dedc1 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ルータ内の関数で、呼び出されたときに現在のミドルウェアを継承してミドルウェアを実行します。 @@ -14,7 +15,7 @@ _Middleware_ 関数は、[request object](/api#req) (`req`) にアクセスで - リクエストレスポンスサイクルを終了します。 - スタック内の次のミドルウェアを呼び出します。 -現在のミドルウェア関数がリクエスト応答サイクルを終了しない場合は、次のミドルウェア関数に制御を渡すために `next()` を呼び出す必要があります。 そうでなければ、リクエストはハングアップのままになります。 そうでなければ、リクエストはハングアップのままになります。 +現在のミドルウェア関数がリクエスト応答サイクルを終了しない場合は、次のミドルウェア関数に制御を渡すために `next()` を呼び出す必要があります。 そうでなければ、リクエストはハングアップのままになります。そうでなければ、リクエストはハングアップのままになります。 次の図はミドルウェア関数呼び出しの要素を示しています。 @@ -53,8 +54,7 @@ Express 5以降、Promiseを返すミドルウェア関数はエラーの拒否 ## 例 -以下は、簡単な「Hello World」エクスプレスアプリケーションの例です。 -以下は、簡単な「Hello World」エクスプレスアプリケーションの例です。 +以下は、簡単な「Hello World」エクスプレスアプリケーションの例です。以下は、簡単な「Hello World」エクスプレスアプリケーションの例です。 The remainder of this article will define and add three middleware functions to the application: one called `myLogger` that prints a simple log message, one called `requestTime` that displays the timestamp of the HTTP request, and one called `validateCookies` that validates incoming cookies. @@ -202,8 +202,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 +427,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/examples.mdx b/src/content/docs/ja/4x/starter/examples.mdx index 5211ad2df3..754af70075 100644 --- a/src/content/docs/ja/4x/starter/examples.mdx +++ b/src/content/docs/ja/4x/starter/examples.mdx @@ -37,8 +37,8 @@ import Alert from '@components/primitives/Alert/Alert.astro'; この情報は、 - Expressjsチームがメンテナンスしていないサードパーティのサイト、製品、またはモジュールを指します。 - ここでの掲載は、 Expressjsプロジェクトチームの推奨または推奨を構成するものではありません。 + Expressjsチームがメンテナンスしていないサードパーティのサイト、製品、またはモジュールを指します。ここでの掲載は、 + Expressjsプロジェクトチームの推奨または推奨を構成するものではありません。 - [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - ORMとして [Prisma](https://www.npmjs.com/package/prisma) を使用する Express をTypeScript で REST API 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/generator.mdx b/src/content/docs/ja/4x/starter/generator.mdx index 13c433e806..08048f0a6f 100644 --- a/src/content/docs/ja/4x/starter/generator.mdx +++ b/src/content/docs/ja/4x/starter/generator.mdx @@ -42,7 +42,7 @@ $ express -h -f, --force force on non-empty directory ``` -例えば、次のように、_myapp_ という名前の Express アプリケーションを作成します。 アプリは現在の作業ディレクトリの _myapp_ というフォルダに作成され、ビューエンジンは Pug に設定されます。 +例えば、次のように、_myapp_ という名前の Express アプリケーションを作成します。アプリは現在の作業ディレクトリの _myapp_ というフォルダに作成され、ビューエンジンは Pug に設定されます。 ```bash $ express --view=pug myapp @@ -119,7 +119,6 @@ PS> $env:DEBUG='myapp:*'; npm start -ジェネレータによって作成されたアプリ構造は、Express アプリケーションを構成するための多くの方法の1つに過ぎません。 -自由にこの構造を使用するか、あなたのニーズに最適に変更してください。 +ジェネレータによって作成されたアプリ構造は、Express アプリケーションを構成するための多くの方法の1つに過ぎません。自由にこの構造を使用するか、あなたのニーズに最適に変更してください。 diff --git a/src/content/docs/ja/4x/starter/hello-world.mdx b/src/content/docs/ja/4x/starter/hello-world.mdx index ca39b80b61..daf43d6071 100644 --- a/src/content/docs/ja/4x/starter/hello-world.mdx +++ b/src/content/docs/ja/4x/starter/hello-world.mdx @@ -7,7 +7,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; -以下に埋め込まれているのは、基本的に作成できる最も簡単なExpressアプリです。 以下に埋め込まれているのは、基本的に作成できる最も簡単なExpressアプリです。 It is a single file app +以下に埋め込まれているのは、基本的に作成できる最も簡単なExpressアプリです。以下に埋め込まれているのは、基本的に作成できる最も簡単なExpressアプリです。 It is a single file app — _not_ what you'd get if you use the [Express generator](/starter/generator), which creates the scaffolding for a full app with numerous JavaScript files, Jade templates, and sub-directories for various purposes. diff --git a/src/content/docs/ja/4x/starter/installing.mdx b/src/content/docs/ja/4x/starter/installing.mdx index 6ca17fe378..37d2da1e05 100644 --- a/src/content/docs/ja/4x/starter/installing.mdx +++ b/src/content/docs/ja/4x/starter/installing.mdx @@ -6,7 +6,7 @@ description: Learn how to install Express.js in your Node.js environment, includ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -始める前に、 [Node.js](https://nodejs.org/) 0.10 以上がインストールされていることを確認してください。 次に、アプリケーションのディレクトリを作成し、その中に移動します。 +始める前に、 [Node.js](https://nodejs.org/) 0.10 以上がインストールされていることを確認してください。次に、アプリケーションのディレクトリを作成し、その中に移動します。 ```bash mkdir myapp @@ -18,8 +18,7 @@ cd myapp -このコマンドを実行すると、アプリケーションの名前やバージョンなど、さまざまなものが表示されます。 -今のところ、RETURNを押すと、ほとんどのデフォルトを受け入れることができます。以下の例外があります。 +このコマンドを実行すると、アプリケーションの名前やバージョンなど、さまざまなものが表示されます。今のところ、RETURNを押すと、ほとんどのデフォルトを受け入れることができます。以下の例外があります。 ``` entry point: (index.js) @@ -27,7 +26,7 @@ entry point: (index.js) `app.js`、またはメインファイルの名前を何でも入力します。 `index.js`にしたい場合は、RETURNを押して、推奨されるデフォルトのファイル名を受け入れます。 -次に、Expressを`myapp`ディレクトリにインストールし、依存関係リストに保存します。 例: +次に、Expressを`myapp`ディレクトリにインストールし、依存関係リストに保存します。例: @@ -79,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/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/behind-proxies.mdx b/src/content/docs/ja/5x/guide/behind-proxies.mdx index 70752e3bee..c9241b65b7 100644 --- a/src/content/docs/ja/5x/guide/behind-proxies.mdx +++ b/src/content/docs/ja/5x/guide/behind-proxies.mdx @@ -5,12 +5,12 @@ description: クライアントの IP アドレスを処理するトラストプ import Alert from '@components/primitives/Alert/Alert.astro'; -リバースプロキシの背後で Express アプリケーションを実行する場合、Express API の中には予想以外の値が返されるものがあります。 これを調整するために `trust proxy` アプリケーションの設定は、Express API のリバースプロキシによって提供された情報を公開するために使用することができます。 最も一般的な問題は、クライアントのIPアドレスを公開するAPIで、リバースプロキシの内部IPアドレスが表示される可能性があります。 これを調整するために `trust proxy` アプリケーションの設定は、Express API のリバースプロキシによって提供された情報を公開するために使用することができます。 最も一般的な問題は、クライアントのIPアドレスを公開するAPIで、リバースプロキシの内部IPアドレスが表示される可能性があります。 +リバースプロキシの背後で Express アプリケーションを実行する場合、Express API の中には予想以外の値が返されるものがあります。 これを調整するために `trust proxy` アプリケーションの設定は、Express API のリバースプロキシによって提供された情報を公開するために使用することができます。 最も一般的な問題は、クライアントのIPアドレスを公開するAPIで、リバースプロキシの内部IPアドレスが表示される可能性があります。これを調整するために `trust proxy` アプリケーションの設定は、Express API のリバースプロキシによって提供された情報を公開するために使用することができます。最も一般的な問題は、クライアントのIPアドレスを公開するAPIで、リバースプロキシの内部IPアドレスが表示される可能性があります。 `trust proxy` の設定では、 -リバースプロキシの正確な設定を理解することが重要です。 この設定はリクエストで提供された値を信頼するためです Express での設定の組み合わせが +リバースプロキシの正確な設定を理解することが重要です。この設定はリクエストで提供された値を信頼するためです Express での設定の組み合わせが リバースプロキシの動作と一致することが重要です。 @@ -25,7 +25,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; `true` の場合、クライアントの IP アドレスは `X-Forwarded-For` ヘッダーの中の一番左のエントリとして理解されます。 -`false` の場合、アプリはクライアントに直接向いていると理解され、クライアントの IP アドレスは `req.socket.remoteAddress` に由来します。 これはデフォルトの設定です。 これはデフォルトの設定です。 +`false` の場合、アプリはクライアントに直接向いていると理解され、クライアントの IP アドレスは `req.socket.remoteAddress` に由来します。 これはデフォルトの設定です。これはデフォルトの設定です。 `true` に設定する場合、信頼されている最後のリバースプロキシが以下のすべての HTTP ヘッダを削除/上書きすることが重要です: `X-Forwarded-For` 。 `X-Forwarded-Host` と `X-Forwarded-Proto` があれば、クライアントが何らかの値を提供できるかもしれません。 @@ -35,7 +35,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; IPアドレス -リバースプロキシとして信頼する IP アドレス、サブネット、または IP アドレスとサブネットの配列。 次のリストに、事前に設定されたサブネット名が表示されます。 次のリストに、事前に設定されたサブネット名が表示されます。 +リバースプロキシとして信頼する IP アドレス、サブネット、または IP アドレスとサブネットの配列。 次のリストに、事前に設定されたサブネット名が表示されます。次のリストに、事前に設定されたサブネット名が表示されます。 - loopback - `127.0.0.1/8`, `::1/128` - linklocal - `169.254.0.0/16`, `fe80::/10` @@ -50,7 +50,7 @@ app.set('trust proxy', 'loopback, linklocal, uniquelocal'); // specify multiple app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); // specify multiple subnets as an array ``` -指定された場合、IPアドレスまたはサブネットはアドレス決定プロセスから除外されます。 アプリケーションサーバーに最も近い信頼できないIPアドレスは、クライアントのIPアドレスとして決定されます。 これは `req.socket.remoteAddress` が信頼されているかどうかをチェックすることで動作します。 その場合、`X-Forwarded-For`内の各アドレスは、最初の信頼されていないアドレスまで右から左にチェックされます。 +指定された場合、IPアドレスまたはサブネットはアドレス決定プロセスから除外されます。 アプリケーションサーバーに最も近い信頼できないIPアドレスは、クライアントのIPアドレスとして決定されます。これは `req.socket.remoteAddress` が信頼されているかどうかをチェックすることで動作します。その場合、`X-Forwarded-For`内の各アドレスは、最初の信頼されていないアドレスまで右から左にチェックされます。 @@ -108,4 +108,4 @@ app.set('trust proxy', (ip: string) => { -`trust proxy` は、 [proxy-addr](https://www.npmjs.com/package/proxy-addr) パッケージを使用して実装されています。 詳細については、そのドキュメントを参照してください。 詳細については、そのドキュメントを参照してください。 +`trust proxy` は、 [proxy-addr](https://www.npmjs.com/package/proxy-addr) パッケージを使用して実装されています。 詳細については、そのドキュメントを参照してください。詳細については、そのドキュメントを参照してください。 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..07c98823ff 100644 --- a/src/content/docs/ja/5x/guide/error-handling.mdx +++ b/src/content/docs/ja/5x/guide/error-handling.mdx @@ -15,10 +15,12 @@ import Alert from '@components/primitives/Alert/Alert.astro'; Express がルートハンドラと ミドルウェアの実行中に発生するすべてのエラーをキャッチすることが重要です。 +### Errors in synchronous code + ルートハンドラとミドルウェア 内の同期コードで発生するエラーは追加の作業を必要としません。 同期コードがエラーをスローする場合、Expressは キャッチして処理します。 例: 同期コードがエラーをスローする場合、Expressは -キャッチして処理します。 例: +キャッチして処理します。例: ```js app.get('/', (req, res) => { @@ -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..cc7d1916f8 100644 --- a/src/content/docs/ja/5x/guide/routing.mdx +++ b/src/content/docs/ja/5x/guide/routing.mdx @@ -14,12 +14,11 @@ 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()` を呼び出して、次のコールバックに -を渡すことが重要です。 -複数のコールバック関数を使用。 コールバック関数に `next` を引数として渡し、関数の本体内で `next()` を呼び出して、次のコールバックに +を渡すことが重要です。複数のコールバック関数を使用。 コールバック関数に `next` を引数として渡し、関数の本体内で `next()` を呼び出して、次のコールバックに を渡すことが重要です。 以下のコードは、非常に基本的なルートの例です。 @@ -88,11 +87,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 +113,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 +160,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 +198,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 +236,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 +256,118 @@ 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 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. +リクエストを処理するために、[ミドルウェア](/guide/using-middleware)のように動作する複数のコールバック関数を指定できます。 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) => { @@ -339,7 +380,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'; @@ -359,17 +400,17 @@ app.get('/user/:id', (req: Request, res: Response) => { この例では: - `GET /user/5` → 最初のルートで処理 → "User 5" を送信 -- `GET /user/0` → 最初のroute ('route')`を呼び出し、次に一致する `/user/:id\` route (ルート) をスキップします。 +- `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'; @@ -379,7 +420,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -複数のコールバック関数がルートを処理できます (`next` オブジェクトを指定してください)。 例: 例: +複数のコールバック関数がルートを処理できます (`next` オブジェクトを指定してください)。例: ```js app.get( @@ -409,7 +450,7 @@ app.get( ); ``` -コールバック関数の配列はルートを処理できます。 例: 例: +コールバック関数の配列はルートを処理できます。 例: ```js const cb0 = function (req, res, next) { @@ -449,7 +490,7 @@ const cb2 = function (req: Request, res: Response) { app.get('/example/c', [cb0, cb1, cb2]); ``` -独立した関数と関数の配列の組み合わせは、ルートを処理することができます。 例: 例: +独立した関数と関数の配列の組み合わせは、ルートを処理することができます。 例: 例: 例: ```js const cb0 = function (req, res, next) { @@ -503,27 +544,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. -| 方法 | 説明 | -| ----------------------------------------------- | ---------------------------------------------------------------------------------- | -| [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()`を使用して定義されたルートハンドラの例です。```js +app +.route('/book') +.get((req, res) => { +res.send('Ge -以下は、`app.route()`を使用して定義されたルートハンドラの例です。 +```` ```js app @@ -537,7 +585,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -557,9 +605,9 @@ app ## express.Router -Use the `express.Router` class to create modular, mountable route handlers. `express.Router` クラスを使用して、モジュール化されたマウント可能なルートハンドラを作成します。 `Router`インスタンスは完全なミドルウェアとルーティングシステムです。そのため、しばしば「ミニアプリ」と呼ばれます。 +`express.Router` クラスを使用して、モジュール化されたマウント可能なルートハンドラを作成します。 `Router`インスタンスは完全なミドルウェアとルーティングシステムです。そのため、しばしば「ミニアプリ」と呼ばれます。 -次の例では、ルータをモジュールとして作成し、ミドルウェア関数をロードします。 いくつかのルートを定義し、メインアプリのパスにルータモジュールをマウントします。 +次の例では、ルータをモジュールとして作成し、ミドルウェア関数をロードします。 いくつかのルートを定義し、メインアプリのパスにルータモジュールをマウントします。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 +700,10 @@ 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 }); -``` +```` 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..a5be1dcda4 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'; @@ -8,18 +8,16 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa _template engine_ を使用すると、アプリケーションで静的なテンプレート ファイルを使用できます。 _template engine_ を使用すると、アプリケーションで静的なテンプレート ファイルを使用できます。 実行時に、テンプレートエンジンはテンプレートファイルの 変数を実際の値に置き換えます。 をクリックして、テンプレートをクライアントに送信する HTML ファイルに変換します。 -このアプローチにより、HTML ページのデザインが容易になります。 -このアプローチにより、HTML ページのデザインが容易になります。 +このアプローチにより、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` ディレクトリです。 +- `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: @@ -27,8 +25,9 @@ To render template files, set the following [application setting properties](/ap Pug のような Express 準拠のテンプレートエンジンは、 `__express(filePath, options, callback)` という名前の関数、 `res.render()` がテンプレートコードのレンダリングを呼び出す をエクスポートします。 -一部のテンプレートエンジンはこの規約に従っていません。 一部のテンプレートエンジンはこの規約に従っていません。 [@ladjs/integrate](https://www.npmjs.com/package/@ladjs/consolidate) +一部のテンプレートエンジンはこの規約に従っていません。一部のテンプレートエンジンはこの規約に従っていません。 [@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..492744d192 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ルータ内の関数で、呼び出されたときに現在のミドルウェアを継承してミドルウェアを実行します。 @@ -14,7 +15,7 @@ _Middleware_ 関数は、[request object](/api#req) (`req`) にアクセスで - リクエストレスポンスサイクルを終了します。 - スタック内の次のミドルウェアを呼び出します。 -現在のミドルウェア関数がリクエスト応答サイクルを終了しない場合は、次のミドルウェア関数に制御を渡すために `next()` を呼び出す必要があります。 そうでなければ、リクエストはハングアップのままになります。 そうでなければ、リクエストはハングアップのままになります。 +現在のミドルウェア関数がリクエスト応答サイクルを終了しない場合は、次のミドルウェア関数に制御を渡すために `next()` を呼び出す必要があります。 そうでなければ、リクエストはハングアップのままになります。そうでなければ、リクエストはハングアップのままになります。 次の図はミドルウェア関数呼び出しの要素を示しています。 @@ -24,8 +25,7 @@ Express 5以降、Promiseを返すミドルウェア関数はエラーの拒否 ## 例 -以下は、簡単な「Hello World」エクスプレスアプリケーションの例です。 -以下は、簡単な「Hello World」エクスプレスアプリケーションの例です。 +以下は、簡単な「Hello World」エクスプレスアプリケーションの例です。以下は、簡単な「Hello World」エクスプレスアプリケーションの例です。 The remainder of this article will define and add three middleware functions to the application: one called `myLogger` that prints a simple log message, one called `requestTime` that displays the timestamp of the HTTP request, and one called `validateCookies` that validates incoming cookies. @@ -173,8 +173,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 +398,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/examples.mdx b/src/content/docs/ja/5x/starter/examples.mdx index 97cef8939a..2b889f3784 100644 --- a/src/content/docs/ja/5x/starter/examples.mdx +++ b/src/content/docs/ja/5x/starter/examples.mdx @@ -40,7 +40,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; この情報は、 -Expressjsチームがメンテナンスしていないサードパーティのサイト、製品、またはモジュールを指します。 ここでの掲載は、 +Expressjsチームがメンテナンスしていないサードパーティのサイト、製品、またはモジュールを指します。ここでの掲載は、 Expressjsプロジェクトチームの推奨または推奨を構成するものではありません。 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/generator.mdx b/src/content/docs/ja/5x/starter/generator.mdx index 13c433e806..08048f0a6f 100644 --- a/src/content/docs/ja/5x/starter/generator.mdx +++ b/src/content/docs/ja/5x/starter/generator.mdx @@ -42,7 +42,7 @@ $ express -h -f, --force force on non-empty directory ``` -例えば、次のように、_myapp_ という名前の Express アプリケーションを作成します。 アプリは現在の作業ディレクトリの _myapp_ というフォルダに作成され、ビューエンジンは Pug に設定されます。 +例えば、次のように、_myapp_ という名前の Express アプリケーションを作成します。アプリは現在の作業ディレクトリの _myapp_ というフォルダに作成され、ビューエンジンは Pug に設定されます。 ```bash $ express --view=pug myapp @@ -119,7 +119,6 @@ PS> $env:DEBUG='myapp:*'; npm start -ジェネレータによって作成されたアプリ構造は、Express アプリケーションを構成するための多くの方法の1つに過ぎません。 -自由にこの構造を使用するか、あなたのニーズに最適に変更してください。 +ジェネレータによって作成されたアプリ構造は、Express アプリケーションを構成するための多くの方法の1つに過ぎません。自由にこの構造を使用するか、あなたのニーズに最適に変更してください。 diff --git a/src/content/docs/ja/5x/starter/hello-world.mdx b/src/content/docs/ja/5x/starter/hello-world.mdx index ca39b80b61..daf43d6071 100644 --- a/src/content/docs/ja/5x/starter/hello-world.mdx +++ b/src/content/docs/ja/5x/starter/hello-world.mdx @@ -7,7 +7,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; -以下に埋め込まれているのは、基本的に作成できる最も簡単なExpressアプリです。 以下に埋め込まれているのは、基本的に作成できる最も簡単なExpressアプリです。 It is a single file app +以下に埋め込まれているのは、基本的に作成できる最も簡単なExpressアプリです。以下に埋め込まれているのは、基本的に作成できる最も簡単なExpressアプリです。 It is a single file app — _not_ what you'd get if you use the [Express generator](/starter/generator), which creates the scaffolding for a full app with numerous JavaScript files, Jade templates, and sub-directories for various purposes. diff --git a/src/content/docs/ja/5x/starter/installing.mdx b/src/content/docs/ja/5x/starter/installing.mdx index bd1abc9172..3bdb106c9e 100644 --- a/src/content/docs/ja/5x/starter/installing.mdx +++ b/src/content/docs/ja/5x/starter/installing.mdx @@ -6,7 +6,7 @@ description: Learn how to install Express.js in your Node.js environment, includ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -始める前に、 [Node.js](https://nodejs.org/) 18 以上のインストールがあることを確認してください。 次に、アプリケーションのディレクトリを作成し、その中に移動します。 +始める前に、 [Node.js](https://nodejs.org/) 18 以上のインストールがあることを確認してください。次に、アプリケーションのディレクトリを作成し、その中に移動します。 ```bash mkdir myapp @@ -18,8 +18,7 @@ cd myapp -このコマンドを実行すると、アプリケーションの名前やバージョンなど、さまざまなものが表示されます。 -今のところ、RETURNを押すと、ほとんどのデフォルトを受け入れることができます。以下の例外があります。 +このコマンドを実行すると、アプリケーションの名前やバージョンなど、さまざまなものが表示されます。今のところ、RETURNを押すと、ほとんどのデフォルトを受け入れることができます。以下の例外があります。 ``` entry point: (index.js) @@ -27,7 +26,7 @@ entry point: (index.js) `app.js`、またはメインファイルの名前を何でも入力します。 `index.js`にしたい場合は、RETURNを押して、推奨されるデフォルトのファイル名を受け入れます。 -次に、Expressを`myapp`ディレクトリにインストールし、依存関係リストに保存します。 例: +次に、Expressを`myapp`ディレクトリにインストールし、依存関係リストに保存します。例: @@ -70,7 +69,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..ee8c9bffc8 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 | | ----------------------------------------------- | ------------------------------------------------------------------------------------- | @@ -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..5b94dc3ee4 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 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,26 @@ 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 | -| ----------------------------------------------- | ------------------------------------------------------------------------------------- | -| [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 using `app.route()`. +|## app.route()You can create chainable route handlers for a rou ```js app @@ -530,7 +576,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -550,9 +596,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 +691,10 @@ 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 }); -``` +```` 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..6a5f32b516 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. @@ -383,11 +411,11 @@ app.get('/user/:id', (req: Request, res: Response) => { 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 +- `GET /user/0` → primeira rota chama `next('route')`, 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. -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. | 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..2abcc9c0e0 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. + ## 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'; @@ -353,17 +397,19 @@ app.get('/user/:id', (req: Request, res: Response) => { 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 +- `GET /user/0` → primeira rota chama `next('route')`, 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. -| 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). + +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,10 @@ 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 }); -``` +```` 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/advanced/developing-template-engines.mdx b/src/content/docs/zh-cn/4x/advanced/developing-template-engines.mdx index 58ba710565..273d16415e 100644 --- a/src/content/docs/zh-cn/4x/advanced/developing-template-engines.mdx +++ b/src/content/docs/zh-cn/4x/advanced/developing-template-engines.mdx @@ -50,7 +50,7 @@ app.set('views', './views'); // specify the views directory app.set('view engine', 'ntl'); // register the template engine ``` -你的应用现在将能够渲染 `.ntl` 文件。 在 `views` 目录中创建一个名为 `index.ntl` 的文件,并写入以下内容。 +你的应用现在将能够渲染 `.ntl` 文件。在 `views` 目录中创建一个名为 `index.ntl` 的文件,并写入以下内容。 ```pug #title# diff --git a/src/content/docs/zh-cn/4x/guide/behind-proxies.mdx b/src/content/docs/zh-cn/4x/guide/behind-proxies.mdx index 98d15d930a..ee23f33b56 100644 --- a/src/content/docs/zh-cn/4x/guide/behind-proxies.mdx +++ b/src/content/docs/zh-cn/4x/guide/behind-proxies.mdx @@ -5,11 +5,11 @@ description: 学习如何配置 Express.js 应用使其在反向代理后正常 import Alert from '@components/primitives/Alert/Alert.astro'; -在反向代理后运行 Express 应用时,部分 Express API 的返回值可能与预期不符。 为此可配置应用设置项 `trust proxy` ,让 Express 接口能够获取反向代理转发的请求信息。 最常见的问题是,用于获取客户端IP的Express接口,获取到的IP实为反向代理的内网地址。 +在反向代理后运行 Express 应用时,部分 Express API 的返回值可能与预期不符。为此可配置应用设置项 `trust proxy` ,让 Express 接口能够获取反向代理转发的请求信息。最常见的问题是,用于获取客户端IP的Express接口,获取到的IP实为反向代理的内网地址。 -配置`trust proxy`设置时,务必清楚反向代理的具体部署架构。 由于该配置会信任请求中携带的参数值,因此Express中的配置必须与反向代理的运行方式完全匹配,这一点至关重要。 +配置`trust proxy`设置时,务必清楚反向代理的具体部署架构。由于该配置会信任请求中携带的参数值,因此Express中的配置必须与反向代理的运行方式完全匹配,这一点至关重要。 @@ -23,7 +23,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; 若设为 `true`,客户端IP地址将被认定为`X-Forwarded-For`请求头中最左侧的条目。 -若设为 `false`,表示应用直接面向客户端,客户端IP地址取自 `req.socket.remoteAddress`。 该值为默认配置。 +若设为 `false`,表示应用直接面向客户端,客户端IP地址取自 `req.socket.remoteAddress`。该值为默认配置。 将此项设为 `true` 时,务必确保最后一级受信反向代理会**移除/覆盖**以下所有HTTP请求头:`X-Forwarded-For`、`X-Forwarded-Host` 和 `X-Forwarded-Proto`,否则客户端可能伪造任意值。 @@ -33,7 +33,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; IP addresses -可配置为一个IP地址、一个子网,或由多个IP地址和子网组成的数组,用于指定可信任的反向代理。 以下列表展示了预配置的子网名称: +可配置为一个IP地址、一个子网,或由多个IP地址和子网组成的数组,用于指定可信任的反向代理。以下列表展示了预配置的子网名称: - loopback - `127.0.0.1/8`, `::1/128` - linklocal - `169.254.0.0/16`, `fe80::/10` @@ -48,14 +48,14 @@ app.set('trust proxy', 'loopback, linklocal, uniquelocal'); // specify multiple app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); // specify multiple subnets as an array ``` -指定后,这些IP地址或子网将被排除在地址判定流程之外,最靠近应用服务器的非受信IP将被认定为客户端IP地址。 其工作原理是检查 `req.socket.remoteAddress` 是否为可信任地址。 若为可信地址,则从右向左检查`X-Forwarded-For`中的每个地址,直至找到第一个非可信地址。 +指定后,这些IP地址或子网将被排除在地址判定流程之外,最靠近应用服务器的非受信IP将被认定为客户端IP地址。其工作原理是检查 `req.socket.remoteAddress` 是否为可信任地址。若为可信地址,则从右向左检查`X-Forwarded-For`中的每个地址,直至找到第一个非可信地址。 Number -使用距离 Express 应用不超过 n 个网络跳数的地址。 `req.socket.remoteAddress` 为第一跳,其余地址从`X-Forwarded-For`请求头中从右向左查找。 取值为 `0` 表示:第一个非可信地址就是 `req.socket.remoteAddress`,即不存在反向代理。 +使用距离 Express 应用不超过 n 个网络跳数的地址。 `req.socket.remoteAddress` 为第一跳,其余地址从`X-Forwarded-For`请求头中从右向左查找。取值为 `0` 表示:第一个非可信地址就是 `req.socket.remoteAddress`,即不存在反向代理。 使用该配置时,必须确保不存在多条长度不同的路径到达 Express 应用,避免客户端与服务的跳数少于配置值,否则客户端可能伪造任意值。 @@ -105,4 +105,4 @@ app.set('trust proxy', (ip: string) => { -`trust proxy` 配置项依托[proxy-addr](https://www.npmjs.com/package/proxy-addr)包实现。 更多详情请参阅该模块文档。 +`trust proxy` 配置项依托[proxy-addr](https://www.npmjs.com/package/proxy-addr)包实现。更多详情请参阅该模块文档。 diff --git a/src/content/docs/zh-cn/4x/guide/debugging.mdx b/src/content/docs/zh-cn/4x/guide/debugging.mdx index beb9dc3f3b..a5fa8c8930 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:*`。 @@ -83,24 +84,121 @@ $ DEBUG=express:* node ./bin/www express:view render "/projects/example/views/index.pug" +1ms ``` -若仅查看来自路由实现的日志,请将 `DEBUG` 的值设置为 `express:router`。 同理,若仅查看来自应用实现的日志,请将 `DEBUG` 的值设置为 `express:application`,以此类推。 +若仅查看来自路由实现的日志,请将 `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..cc688aac01 100644 --- a/src/content/docs/zh-cn/4x/guide/error-handling.mdx +++ b/src/content/docs/zh-cn/4x/guide/error-handling.mdx @@ -11,7 +11,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; 确保 Express 能够捕获路由处理器和中间件运行时发生的所有错误,这一点至关重要。 -路由处理函数与中间件内同步代码产生的错误无需额外处理。 倘若同步代码抛出错误,Express 会捕获并处理该错误。 举个例子: +路由处理函数与中间件内同步代码产生的错误无需额外处理。倘若同步代码抛出错误,Express 会捕获并处理该错误。举个例子: ```js app.get('/', (req, res) => { @@ -27,7 +27,7 @@ app.get('/', (req: Request, res: Response) => { }); ``` -对于路由处理函数和中间件调用的异步函数所返回的错误,你必须将它们传递给 `next()` 函数,Express 会在该函数中捕获并处理这些错误。 举个例子: +对于路由处理函数和中间件调用的异步函数所返回的错误,你必须将它们传递给 `next()` 函数,Express 会在该函数中捕获并处理这些错误。举个例子: ```js app.get('/', (req, res, next) => { @@ -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 会将当前请求视作出错,并跳过后续所有非错误处理的路由与中间件函数。 @@ -104,9 +117,9 @@ app.get('/', [ ]); ``` -在上述示例中,`next` 被作为 `fs.writeFile` 的回调函数传入,无论是否存在错误都会被调用。 若无错误,则执行第二个处理函数;否则 Express 会捕获并处理该错误。 +在上述示例中,`next` 被作为 `fs.writeFile` 的回调函数传入,无论是否存在错误都会被调用。若无错误,则执行第二个处理函数;否则 Express 会捕获并处理该错误。 -你必须捕获在路由处理程序或中间件中调用的异步代码里发生的错误,并将它们传递给 Express 进行处理。 举个例子: +你必须捕获在路由处理程序或中间件中调用的异步代码里发生的错误,并将它们传递给 Express 进行处理。举个例子: ```js app.get('/', (req, res, next) => { @@ -134,9 +147,9 @@ app.get('/', (req: Request, res: Response, next: NextFunction) => { }); ``` -上述示例使用 `try...catch` 代码块捕获异步代码中的错误,并将其传递给 Express。 如果省略 `try...catch` 代码块,Express 将无法捕获该错误,因为它不属于同步处理程序代码的一部分。 +上述示例使用 `try...catch` 代码块捕获异步代码中的错误,并将其传递给 Express。如果省略 `try...catch` 代码块,Express 将无法捕获该错误,因为它不属于同步处理程序代码的一部分。 -使用 Promise 来避免 `try...catch` 代码块的开销,或在使用返回 Promise 的函数时采用此方式。 举个例子: +使用 Promise 来避免 `try...catch` 代码块的开销,或在使用返回 Promise 的函数时采用此方式。举个例子: ```js app.get('/', (req, res, next) => { @@ -160,9 +173,9 @@ 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. -你也可以使用处理程序链,将异步代码简化为简单逻辑,从而依靠同步错误捕获机制。 举个例子: +你也可以使用处理程序链,将异步代码简化为简单逻辑,从而依靠同步错误捕获机制。举个例子: ```js app.get('/', [ @@ -196,15 +209,16 @@ 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 能够接收到错误。 ## 默认错误处理程序 -Express 内置了错误处理程序,可处理应用中可能出现的所有错误。 这个默认的错误处理中间件函数会被添加到中间件函数栈的末尾。 +Express 内置了错误处理程序,可处理应用中可能出现的所有错误。这个默认的错误处理中间件函数会被添加到中间件函数栈的末尾。 -如果你将错误传递给 `next()`,但未在自定义错误处理程序中处理它,该错误将由内置错误处理程序处理;错误信息和堆栈追踪信息会被返回给客户端。 生产环境中不会包含堆栈追踪信息。 +如果你将错误传递给 `next()`,但未在自定义错误处理程序中处理它,该错误将由内置错误处理程序处理;错误信息和堆栈追踪信息会被返回给客户端。生产环境中不会包含堆栈追踪信息。 @@ -214,7 +228,7 @@ Express 内置了错误处理程序,可处理应用中可能出现的所有错 当错误信息被输出时,响应中会附加以下信息: -- `res.statusCode` 会从 `err.status`(或 `err.statusCode`)中获取设置。 如果该值不在 4xx 或 5xx 范围内,则会被设置为 500。 +- `res.statusCode` 会从 `err.status`(或 `err.statusCode`)中获取设置。如果该值不在 4xx 或 5xx 范围内,则会被设置为 500。 - `res.statusMessage` 会根据状态码自动设置。 - 生产环境中,响应主体会展示状态码信息的 HTML 页面;其他环境下则会展示 `err.stack` 堆栈信息。 - `err.headers` 对象中定义的所有响应头。 @@ -252,7 +266,7 @@ Other error handling middleware can be found at [Express middleware](/resources/ ## 编写错误处理程序 错误处理中间件函数的定义方式与其他中间件函数基本相同,区别在于错误处理函数包含四个参数而非三个: -`(err, req, res, next)`。 举个例子: +`(err, req, res, next)`。举个例子: ```js app.use((err, req, res, next) => { @@ -323,7 +337,7 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { 中间件函数内的响应可以是任意格式,例如 HTML 错误页面、简单消息或 JSON 字符串。 -出于组织结构(以及高级框架)的目的,你可以定义多个错误处理中间件函数,这与你使用常规中间件函数的方式非常相似。 例如,为使用 `XHR` 发起的请求和未使用 `XHR` 发起的请求分别定义错误处理程序: +出于组织结构(以及高级框架)的目的,你可以定义多个错误处理中间件函数,这与你使用常规中间件函数的方式非常相似。例如,为使用 `XHR` 发起的请求和未使用 `XHR` 发起的请求分别定义错误处理程序: ```cjs title="index.cjs" const bodyParser = require('body-parser'); @@ -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..36e1762355 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,12 +5,12 @@ 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`。 -修改全局原型会影响同一进程中所有已加载的 Express 应用。 如果需要,你可以在创建新应用后仅修改应用专属原型,从而实现仅针对当前应用的修改。 +修改全局原型会影响同一进程中所有已加载的 Express 应用。如果需要,你可以在创建新应用后仅修改应用专属原型,从而实现仅针对当前应用的修改。 ## 方法 @@ -46,7 +46,7 @@ app.response.sendStatus = function ( } as Response['sendStatus']; ``` -上述实现彻底更改了`res.sendStatus`原本的方法签名。 该方法现在可接收状态码、编码类型以及要发送给客户端的消息。 +上述实现彻底更改了`res.sendStatus`原本的方法签名。该方法现在可接收状态码、编码类型以及要发送给客户端的消息。 In TypeScript, augmenting `express-serve-static-core` adds the new overload to the `Response` type so call sites such as `res.sendStatus(404, 'application/json', body)` type-check. The assignment is cast with `as Response['sendStatus']` because replacing a method with a different signature cannot be checked against the original declaration. @@ -67,7 +67,7 @@ Express API 中的属性分为两类: 第二类属性可通过 Express API 扩展接口进行重写。 -以下代码重写了`req.ip`值的获取方式。 现在,它仅返回 `Client-IP` 请求头的值。 +以下代码重写了`req.ip`值的获取方式。现在,它仅返回 `Client-IP` 请求头的值。 ```js Object.defineProperty(app.request, 'ip', { @@ -158,9 +158,9 @@ signature, because the method did not previously exist on the type. ## Prototype -为了提供 Express API,传递给 Express 的请求/响应对象(例如通过 `app(req, res)`)需要继承自相同的原型链。 默认情况下,请求对象继承自 `http.IncomingRequest.prototype`,响应对象继承自 `http.ServerResponse.prototype`。 +为了提供 Express API,传递给 Express 的请求/响应对象(例如通过 `app(req, res)`)需要继承自相同的原型链。默认情况下,请求对象继承自 `http.IncomingRequest.prototype`,响应对象继承自 `http.ServerResponse.prototype`。 -除非必要,否则建议仅在应用层面执行此操作,而非全局层面。 此外,请注意所使用的原型需尽可能与默认原型的功能保持一致。 +除非必要,否则建议仅在应用层面执行此操作,而非全局层面。此外,请注意所使用的原型需尽可能与默认原型的功能保持一致。 ```js // Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse diff --git a/src/content/docs/zh-cn/4x/guide/routing.mdx b/src/content/docs/zh-cn/4x/guide/routing.mdx index 3cde7a4ca4..7648e530e3 100644 --- a/src/content/docs/zh-cn/4x/guide/routing.mdx +++ b/src/content/docs/zh-cn/4x/guide/routing.mdx @@ -7,15 +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 +85,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 +111,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 +238,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 +300,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 +371,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) => { @@ -386,7 +418,7 @@ app.get('/user/:id', (req: Request, res: Response) => { 路由处理程序可以采用函数、函数数组或二者结合的形式,如下示例所示。 -单个回调函数即可处理一个路由。 举个例子: +单个回调函数即可处理一个路由。举个例子: ```js app.get('/example/a', (req, res) => { @@ -402,7 +434,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -多个回调函数可以处理同一个路由(请确保你指定了 `next` 对象)。 举个例子: +多个回调函数可以处理同一个路由(请确保你指定了 `next` 对象)。举个例子: ```js app.get( @@ -432,7 +464,7 @@ app.get( ); ``` -一个回调函数数组可以处理一个路由。 举个例子: +一个回调函数数组可以处理一个路由。举个例子: ```js const cb0 = function (req, res, next) { @@ -472,7 +504,7 @@ const cb2 = function (req: Request, res: Response) { app.get('/example/c', [cb0, cb1, cb2]); ``` -独立函数与函数数组组合使用即可处理一个路由。 举个例子: +独立函数与函数数组组合使用即可处理一个路由。举个例子: ```js const cb0 = function (req, res, next) { @@ -526,7 +558,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 | 描述 | | ----------------------------------------------- | ---------------------------------------------------- | @@ -542,8 +574,8 @@ app.get( ## app.route() -你可以使用 `app.route()` 为路由路径创建可链式调用的路由处理程序。 -由于路径在单个位置指定,因此创建模块化路由十分有用,同时还能减少冗余和拼写错误。 For more information about routes, see: [Router() documentation](/api/router). +你可以使用 `app.route()` 为路由路径创建可链式调用的路由处理程序。你可以使用 `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 +611,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 +708,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..b283eab363 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) => { }); ``` -该示例展示了一条路由及其处理函数(中间件体系)。 该函数处理指向 `/user/:id` 路径的 GET 请求。 +### 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 -该示例展示了一个中间件子栈,用于处理 `/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'); @@ -503,12 +524,6 @@ app.use('/admin', router, (req: Request, res: Response) => { ## 错误处理中间件 - - -错误处理中间件始终接收**四个**参数。 你必须传入**四个参数**,才能将其标识为错误处理中间件函数。 即使你不需要使用 `next` 对象,也必须声明它,以保持函数签名不变。 否则,`next` 对象会被解析为常规中间件,从而无法处理错误。 - - - 定义错误处理中间件函数的方式与其他中间件一致,唯一区别是它接收四个参数而非三个,标准函数签名为:`(err, req, res, next)`。 ```js @@ -527,16 +542,28 @@ 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. + + ## 内置中间件 -从 4.x 版本开始,Express 不再依赖 [Connect](https://github.com/senchalabs/connect)。 之前包含在 Express 中的中间件函数,现在已经拆分到独立的模块中;查看[中间件函数列表](https://github.com/senchalabs/connect#middleware)。 +从 4.x 版本开始,Express 不再依赖 [Connect](https://github.com/senchalabs/connect)。之前包含在 Express 中的中间件函数,现在已经拆分到独立的模块中;查看[中间件函数列表](https://github.com/senchalabs/connect#middleware)。 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..ca5de7ac37 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,23 +1,21 @@ --- 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'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -模板引擎能够让你在应用中使用静态模板文件。 运行时,模板引擎会将模板文件中的变量替换为实际值,并把模板转换成HTML文件发送至客户端。 -这种方式能够简化HTML页面的开发。 +模板引擎能够让你在应用中使用静态模板文件。运行时,模板引擎会将模板文件中的变量替换为实际值,并把模板转换成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')`。 +- `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 +23,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. @@ -45,7 +44,7 @@ html h1= message ``` -创建一条路由来渲染`index.pug`文件。 如果未配置`view engine`属性,则必须指明视图文件的后缀名。 否则可以省略文件后缀。 +创建一条路由来渲染`index.pug`文件。如果未配置`view engine`属性,则必须指明视图文件的后缀名。否则可以省略文件后缀。 ```js app.get('/', (req, res) => { @@ -63,4 +62,4 @@ app.get('/', (req: Request, res: Response) => { 当访问首页时,`index.pug` 文件会被渲染成 HTML。 -视图引擎缓存不会缓存模板渲染后的输出内容,仅缓存原始模板文件本身。 即便开启缓存,每次请求视图仍会重新渲染。 +视图引擎缓存不会缓存模板渲染后的输出内容,仅缓存原始模板文件本身。即便开启缓存,每次请求视图仍会重新渲染。 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..438ed3dc20 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 路由器中的一个函数,调用该函数时,会执行当前中间件之后的下一个中间件。 @@ -14,7 +15,7 @@ _Middleware_ functions are functions that have access to the [request object](/a - 终止请求-响应周期。 - 调用堆栈中的下一个中间件。 -如果当前中间件函数没有终止请求-响应周期,它必须调用 `next()` 以将控制权传递给下一个中间件函数。 否则,请求将会被挂起。 +如果当前中间件函数没有终止请求-响应周期,它必须调用 `next()` 以将控制权传递给下一个中间件函数。否则,请求将会被挂起。 下图展示了中间件函数调用的组成要素: @@ -53,8 +54,7 @@ _Middleware_ functions are functions that have access to the [request object](/a ## 示例 -以下是一个简单的 Express “Hello World” 应用示例。 -本文的后续部分将为该应用定义并添加三个中间件函数: +以下是一个简单的 Express “Hello World” 应用示例。本文的后续部分将为该应用定义并添加三个中间件函数: 一个名为 `myLogger`,用于打印简单的日志信息;一个名为 `requestTime`,用于显示 HTTP 请求的时间戳;还有一个名为 `validateCookies`,用于验证传入的 Cookie。 ```cjs title="index.cjs" @@ -94,7 +94,7 @@ app.listen(3000); ### 中间件函数 myLogger -以下是一个名为 `myLogger` 的简单中间件函数示例。 当对应用的请求经过该函数时,它只会打印 "LOGGED"。 该中间件函数被赋值给了一个名为 `myLogger` 的变量。 +以下是一个名为 `myLogger` 的简单中间件函数示例。当对应用的请求经过该函数时,它只会打印 "LOGGED"。该中间件函数被赋值给了一个名为 `myLogger` 的变量。 ```js const myLogger = function (req, res, next) { @@ -120,12 +120,11 @@ needed. -注意上述代码中对 `next()` 的调用。 调用该函数会执行应用中的下一个中间件函数。 `next()` 函数并非 Node.js 或 Express API 的一部分,而是传递给中间件函数的第三个参数。 `next()` 函数可以被命名为任意名称,但按照惯例,它始终被命名为 `next`。 为避免混淆,请始终遵循此命名惯例。 +注意上述代码中对 `next()` 的调用。调用该函数会执行应用中的下一个中间件函数。 `next()` 函数并非 Node.js 或 Express API 的一部分,而是传递给中间件函数的第三个参数。 `next()` 函数可以被命名为任意名称,但按照惯例,它始终被命名为 `next`。为避免混淆,请始终遵循此命名惯例。 -加载中间件函数时,需调用 `app.use()` 并传入该中间件函数。 -例如,以下代码在根路径(/)路由之前加载 `myLogger` 中间件函数。 +加载中间件函数时,需调用 `app.use()` 并传入该中间件函数。例如,以下代码在根路径(/)路由之前加载 `myLogger` 中间件函数。 ```cjs title="index.cjs" const express = require('express'); @@ -193,7 +192,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). @@ -237,7 +237,7 @@ const requestTime = function (req: Request, res: Response, next: NextFunction) { }; ``` -该应用现在使用了 `requestTime` 中间件函数。 此外,根路径路由的回调函数使用了中间件函数挂载到`req`(请求对象)上的属性。 +该应用现在使用了 `requestTime` 中间件函数。此外,根路径路由的回调函数使用了中间件函数挂载到`req`(请求对象)上的属性。 ```cjs title="index.cjs" const express = require('express'); @@ -405,13 +405,17 @@ app.listen(3000); -注意 `next()` 是在 `await cookieValidator(req.cookies)` 之后调用的。 这能确保如果 `cookieValidator` 状态变为已兑现,堆栈中的下一个中间件将会被调用。 如果你向 `next()` 函数传入任何内容(字符串 `'route'` 或 `'router'` 除外),Express 会将当前请求视为错误,并跳过所有剩余的非错误处理路由和中间件函数。 +注意 `next()` 是在 `await cookieValidator(req.cookies)` 之后调用的。这能确保如果 `cookieValidator` 状态变为已兑现,堆栈中的下一个中间件将会被调用。如果你向 `next()` 函数传入任何内容(字符串 `'route'` 或 `'router'` 除外),Express 会将当前请求视为错误,并跳过所有剩余的非错误处理路由和中间件函数。 -由于你可以访问请求对象、响应对象、堆栈中的下一个中间件函数以及整个 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/examples.mdx b/src/content/docs/zh-cn/4x/starter/examples.mdx index e4c31a74ea..3ca748248d 100644 --- a/src/content/docs/zh-cn/4x/starter/examples.mdx +++ b/src/content/docs/zh-cn/4x/starter/examples.mdx @@ -36,7 +36,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; 以下是一些包含更复杂集成的示例。 - 这些信息指的是第三方站点、产品或模块,它们不是由Expressjs团队维护的。 此处的罗列并不代表 Express + 这些信息指的是第三方站点、产品或模块,它们不是由Expressjs团队维护的。此处的罗列并不代表 Express 项目团队的认可或推荐。 diff --git a/src/content/docs/zh-cn/4x/starter/faq.mdx b/src/content/docs/zh-cn/4x/starter/faq.mdx index 7305ba9c14..3da60ea3dc 100644 --- a/src/content/docs/zh-cn/4x/starter/faq.mdx +++ b/src/content/docs/zh-cn/4x/starter/faq.mdx @@ -3,11 +3,13 @@ title: FAQ  常见问题解答 description: 查找有关 Express.js 的常见问题解答,涵盖应用程序架构、数据模型、身份验证、模板引擎、错误处理等相关主题。 --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## 我应该如何组织我的应用程序? -这个问题没有标准答案。 答案取决于你的应用规模以及参与开发的团队。 为实现最大限度的灵活性,Express 不会对项目结构做任何强制限定。 +这个问题没有标准答案。答案取决于你的应用规模以及参与开发的团队。为实现最大限度的灵活性,Express 不会对项目结构做任何强制限定。 -路由和其他应用专属逻辑可拆分至任意数量文件,并采用你偏好的任意目录结构存放。 可参考下方示例获取项目结构设计思路: +路由和其他应用专属逻辑可拆分至任意数量文件,并采用你偏好的任意目录结构存放。可参考下方示例获取项目结构设计思路: - [Route listings](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-L47) - [Route map](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) @@ -19,25 +21,27 @@ description: 查找有关 Express.js 的常见问题解答,涵盖应用程序 ## 如何定义模型? -Express 本身不包含数据库相关概念。 这一概念交由第三方 Node 模块实现,让你能够与几乎所有数据库进行交互。 +Express 本身不包含数据库相关概念。这一概念交由第三方 Node 模块实现,让你能够与几乎所有数据库进行交互。 See [LoopBack](http://loopback.io) for an Express-based framework that is centered around models. ## 如何实现用户身份验证? -身份验证同样是一项带有主观选型倾向的功能,Express 并未涉足该领域。 你可以选用任意你想要的身份验证方案。 -如需实现简易的用户名/密码验证方案,可参考[该示例](https://github.com/expressjs/express/tree/master/examples/auth)。 +身份验证同样是一项带有主观选型倾向的功能,Express 并未涉足该领域。你可以选用任意你想要的身份验证方案。如需实现简易的用户名/密码验证方案,可参考[该示例](https://github.com/expressjs/express/tree/master/examples/auth)。 ## Express 支持哪些模板引擎? -Express 支持所有符合 `(path, locals, callback)` 入参规范的模板引擎。 -如需统一各类模板引擎的接口与缓存机制,可查看 [consolidate.js](https://github.com/visionmedia/consolidate.js) 项目以获取相关支持。 未列入清单的模板引擎也可能兼容 Express 的调用规范。 +Express 支持所有符合 `(path, locals, callback)` 入参规范的模板引擎。如需统一各类模板引擎的接口与缓存机制,可查看 [consolidate.js](https://github.com/visionmedia/consolidate.js) 项目以获取相关支持。未列入清单的模板引擎也可能兼容 Express 的调用规范。 + + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. -For more information, see [Using template engines with Express](/guide/using-template-engines). + ## 如何处理 404 响应? -在 Express 中,404 响应并非由错误导致,因此错误处理中间件不会捕获这类响应。 出现这种行为的原因是,404 响应仅表示没有其他待执行的操作;换言之,Express 已执行完所有中间件函数和路由,但未找到任何能够响应请求的处理逻辑。 你只需在中间件栈的最底部(所有其他函数之后)添加一个中间件函数来处理 404 响应即可: +在 Express 中,404 响应并非由错误导致,因此错误处理中间件不会捕获这类响应。出现这种行为的原因是,404 响应仅表示没有其他待执行的操作;换言之,Express 已执行完所有中间件函数和路由,但未找到任何能够响应请求的处理逻辑。你只需在中间件栈的最底部(所有其他函数之后)添加一个中间件函数来处理 404 响应即可: ```js app.use((req, res, next) => { @@ -75,13 +79,15 @@ 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? -无需额外操作! 无需使用 `res.render()` 函数来“渲染” HTML。 -如果你需要响应指定的文件,请使用 `res.sendFile()` 函数。 -如果你要从一个目录提供多个静态资源,请使用 `express.static()` 中间件函数。 +无需额外操作!无需使用 `res.render()` 函数来“渲染” HTML。如果你需要响应指定的文件,请使用 `res.sendFile()` 函数。如果你要从一个目录提供多个静态资源,请使用 `express.static()` 中间件函数。 ## Express 需要哪个版本的 Node.js? diff --git a/src/content/docs/zh-cn/4x/starter/generator.mdx b/src/content/docs/zh-cn/4x/starter/generator.mdx index 1bbc4ad151..cc10fe742e 100644 --- a/src/content/docs/zh-cn/4x/starter/generator.mdx +++ b/src/content/docs/zh-cn/4x/starter/generator.mdx @@ -42,7 +42,7 @@ $ express -h -f, --force force on non-empty directory ``` -例如,以下命令会创建一个名为 _myapp_ 的 Express 应用。 此应用将创建在当前工作目录下名为 _myapp_ 的文件夹中,并且视图引擎将设置为 Pug: +例如,以下命令会创建一个名为 _myapp_ 的 Express 应用。此应用将创建在当前工作目录下名为 _myapp_ 的文件夹中,并且视图引擎将设置为 Pug: ```bash $ express --view=pug myapp @@ -119,7 +119,6 @@ PS> $env:DEBUG='myapp:*'; npm start -生成器创建的应用结构只是 Express 应用多种结构方案中的一种。 -你可以随意使用此结构,或根据你的需求对其进行修改。 +生成器创建的应用结构只是 Express 应用多种结构方案中的一种。你可以随意使用此结构,或根据你的需求对其进行修改。 diff --git a/src/content/docs/zh-cn/4x/starter/hello-world.mdx b/src/content/docs/zh-cn/4x/starter/hello-world.mdx index ff31016a60..e26d1fbd42 100644 --- a/src/content/docs/zh-cn/4x/starter/hello-world.mdx +++ b/src/content/docs/zh-cn/4x/starter/hello-world.mdx @@ -7,7 +7,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; -下面展示的是一个本质上最简单的 Express 应用。 这是一个单文件应用—而不是使用 [Express 生成器](/en/starter/generator) 所生成的项目结构,后者会创建一个完整应用的脚手架,包含多个 JavaScript 文件、Jade 模板,以及用于不同用途的子目录。 +下面展示的是一个本质上最简单的 Express 应用。这是一个单文件应用—而不是使用 [Express 生成器](/en/starter/generator) 所生成的项目结构,后者会创建一个完整应用的脚手架,包含多个 JavaScript 文件、Jade 模板,以及用于不同用途的子目录。 @@ -55,7 +55,7 @@ app.listen(port, () => { }); ``` -该应用启动一个服务器,并在 3000 端口监听连接请求。 当请求根 URL(`/`)或“ _route_”时,该应用会返回“Hello World!”。 对于其他所有路径,它都会返回 **404 Not Found**。 +该应用启动一个服务器,并在 3000 端口监听连接请求。当请求根 URL(`/`)或“ _route_”时,该应用会返回“Hello World!”。对于其他所有路径,它都会返回 **404 Not Found**。 ## 本地运行 diff --git a/src/content/docs/zh-cn/4x/starter/installing.mdx b/src/content/docs/zh-cn/4x/starter/installing.mdx index 9e1a6cb7d1..b9d0b2d4be 100644 --- a/src/content/docs/zh-cn/4x/starter/installing.mdx +++ b/src/content/docs/zh-cn/4x/starter/installing.mdx @@ -6,28 +6,26 @@ description: Learn how to install Express.js in your Node.js environment, includ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -开始之前,请确保已安装 [Node.js](https://nodejs.org/) 0.10 或更高版本。 然后,为你的应用创建一个目录并进入该目录。 +开始之前,请确保已安装 [Node.js](https://nodejs.org/) 0.10 或更高版本。然后,为你的应用创建一个目录并进入该目录。 ```bash mkdir myapp cd myapp ``` -使用 `npm init` 命令为你的应用创建一个 `package.json` 文件。 -有关 `package.json` 工作机制的更多信息,请参阅 [npm 的 package.json 处理细则](https://docs.npmjs.com/files/package.json)。 +使用 `npm init` 命令为你的应用创建一个 `package.json` 文件。有关 `package.json` 工作机制的更多信息,请参阅 [npm 的 package.json 处理细则](https://docs.npmjs.com/files/package.json)。 -该命令会提示你输入一些信息,例如应用的名称和版本号。 -目前,你可以直接按回车键接受大多数默认值,但以下情况除外: +该命令会提示你输入一些信息,例如应用的名称和版本号。目前,你可以直接按回车键接受大多数默认值,但以下情况除外: ``` entry point: (index.js) ``` -输入 `app.js`,或者你希望作为主文件的其他名称。 如果希望使用 `index.js`,直接按回车键接受系统建议的默认文件名即可。 +输入 `app.js`,或者你希望作为主文件的其他名称。如果希望使用 `index.js`,直接按回车键接受系统建议的默认文件名即可。 -现在,在 `myapp` 目录中安装 Express,并将其保存到依赖列表中。 举个例子: +现在,在 `myapp` 目录中安装 Express,并将其保存到依赖列表中。举个例子: @@ -37,7 +35,7 @@ entry point: (index.js) -默认情况下,在 npm 5.0 及以上版本中,`npm install` 会将模块添加到 `dependencies` 列表中。 之后,在应用目录中运行 `npm install` 将会自动安装 `dependencies` 列表中的模块。 +默认情况下,在 npm 5.0 及以上版本中,`npm install` 会将模块添加到 `dependencies` 列表中。之后,在应用目录中运行 `npm install` 将会自动安装 `dependencies` 列表中的模块。 @@ -76,7 +74,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..6ed70d9d41 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` 中间件函数。 @@ -71,7 +72,7 @@ http://localhost:3000/static/images/bg.png http://localhost:3000/static/hello.html ``` -但是,你提供给 `express.static` 函数的路径是相对于你启动 `node` 进程的目录而言的。 如果你从其他目录启动 Express 应用,使用你要托管的目录的绝对路径会更安全: +但是,你提供给 `express.static` 函数的路径是相对于你启动 `node` 进程的目录而言的。如果你从其他目录启动 Express 应用,使用你要托管的目录的绝对路径会更安全: ```cjs title="index.cjs" const path = require('path'); @@ -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/advanced/developing-template-engines.mdx b/src/content/docs/zh-cn/5x/advanced/developing-template-engines.mdx index 58ba710565..273d16415e 100644 --- a/src/content/docs/zh-cn/5x/advanced/developing-template-engines.mdx +++ b/src/content/docs/zh-cn/5x/advanced/developing-template-engines.mdx @@ -50,7 +50,7 @@ app.set('views', './views'); // specify the views directory app.set('view engine', 'ntl'); // register the template engine ``` -你的应用现在将能够渲染 `.ntl` 文件。 在 `views` 目录中创建一个名为 `index.ntl` 的文件,并写入以下内容。 +你的应用现在将能够渲染 `.ntl` 文件。在 `views` 目录中创建一个名为 `index.ntl` 的文件,并写入以下内容。 ```pug #title# diff --git a/src/content/docs/zh-cn/5x/guide/behind-proxies.mdx b/src/content/docs/zh-cn/5x/guide/behind-proxies.mdx index 98d15d930a..ee23f33b56 100644 --- a/src/content/docs/zh-cn/5x/guide/behind-proxies.mdx +++ b/src/content/docs/zh-cn/5x/guide/behind-proxies.mdx @@ -5,11 +5,11 @@ description: 学习如何配置 Express.js 应用使其在反向代理后正常 import Alert from '@components/primitives/Alert/Alert.astro'; -在反向代理后运行 Express 应用时,部分 Express API 的返回值可能与预期不符。 为此可配置应用设置项 `trust proxy` ,让 Express 接口能够获取反向代理转发的请求信息。 最常见的问题是,用于获取客户端IP的Express接口,获取到的IP实为反向代理的内网地址。 +在反向代理后运行 Express 应用时,部分 Express API 的返回值可能与预期不符。为此可配置应用设置项 `trust proxy` ,让 Express 接口能够获取反向代理转发的请求信息。最常见的问题是,用于获取客户端IP的Express接口,获取到的IP实为反向代理的内网地址。 -配置`trust proxy`设置时,务必清楚反向代理的具体部署架构。 由于该配置会信任请求中携带的参数值,因此Express中的配置必须与反向代理的运行方式完全匹配,这一点至关重要。 +配置`trust proxy`设置时,务必清楚反向代理的具体部署架构。由于该配置会信任请求中携带的参数值,因此Express中的配置必须与反向代理的运行方式完全匹配,这一点至关重要。 @@ -23,7 +23,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; 若设为 `true`,客户端IP地址将被认定为`X-Forwarded-For`请求头中最左侧的条目。 -若设为 `false`,表示应用直接面向客户端,客户端IP地址取自 `req.socket.remoteAddress`。 该值为默认配置。 +若设为 `false`,表示应用直接面向客户端,客户端IP地址取自 `req.socket.remoteAddress`。该值为默认配置。 将此项设为 `true` 时,务必确保最后一级受信反向代理会**移除/覆盖**以下所有HTTP请求头:`X-Forwarded-For`、`X-Forwarded-Host` 和 `X-Forwarded-Proto`,否则客户端可能伪造任意值。 @@ -33,7 +33,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; IP addresses -可配置为一个IP地址、一个子网,或由多个IP地址和子网组成的数组,用于指定可信任的反向代理。 以下列表展示了预配置的子网名称: +可配置为一个IP地址、一个子网,或由多个IP地址和子网组成的数组,用于指定可信任的反向代理。以下列表展示了预配置的子网名称: - loopback - `127.0.0.1/8`, `::1/128` - linklocal - `169.254.0.0/16`, `fe80::/10` @@ -48,14 +48,14 @@ app.set('trust proxy', 'loopback, linklocal, uniquelocal'); // specify multiple app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); // specify multiple subnets as an array ``` -指定后,这些IP地址或子网将被排除在地址判定流程之外,最靠近应用服务器的非受信IP将被认定为客户端IP地址。 其工作原理是检查 `req.socket.remoteAddress` 是否为可信任地址。 若为可信地址,则从右向左检查`X-Forwarded-For`中的每个地址,直至找到第一个非可信地址。 +指定后,这些IP地址或子网将被排除在地址判定流程之外,最靠近应用服务器的非受信IP将被认定为客户端IP地址。其工作原理是检查 `req.socket.remoteAddress` 是否为可信任地址。若为可信地址,则从右向左检查`X-Forwarded-For`中的每个地址,直至找到第一个非可信地址。 Number -使用距离 Express 应用不超过 n 个网络跳数的地址。 `req.socket.remoteAddress` 为第一跳,其余地址从`X-Forwarded-For`请求头中从右向左查找。 取值为 `0` 表示:第一个非可信地址就是 `req.socket.remoteAddress`,即不存在反向代理。 +使用距离 Express 应用不超过 n 个网络跳数的地址。 `req.socket.remoteAddress` 为第一跳,其余地址从`X-Forwarded-For`请求头中从右向左查找。取值为 `0` 表示:第一个非可信地址就是 `req.socket.remoteAddress`,即不存在反向代理。 使用该配置时,必须确保不存在多条长度不同的路径到达 Express 应用,避免客户端与服务的跳数少于配置值,否则客户端可能伪造任意值。 @@ -105,4 +105,4 @@ app.set('trust proxy', (ip: string) => { -`trust proxy` 配置项依托[proxy-addr](https://www.npmjs.com/package/proxy-addr)包实现。 更多详情请参阅该模块文档。 +`trust proxy` 配置项依托[proxy-addr](https://www.npmjs.com/package/proxy-addr)包实现。更多详情请参阅该模块文档。 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..5bb4c9d3a7 100644 --- a/src/content/docs/zh-cn/5x/guide/error-handling.mdx +++ b/src/content/docs/zh-cn/5x/guide/error-handling.mdx @@ -11,7 +11,9 @@ import Alert from '@components/primitives/Alert/Alert.astro'; 确保 Express 能够捕获路由处理器和中间件运行时发生的所有错误,这一点至关重要。 -路由处理函数与中间件内同步代码产生的错误无需额外处理。 倘若同步代码抛出错误,Express 会捕获并处理该错误。 举个例子: +### Errors in synchronous code + +路由处理函数与中间件内同步代码产生的错误无需额外处理。倘若同步代码抛出错误,Express 会捕获并处理该错误。举个例子: ```js app.get('/', (req, res) => { @@ -27,96 +29,68 @@ 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); - } - }); -}); -``` +### 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); - } - }); -}); -``` - -从 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); }); ``` -如果 `getUserById` 抛出错误或被拒绝(reject),`next` 将会使用抛出的错误或被拒绝的值来调用。 如果未提供拒绝值,则会使用 Express 路由内置的默认错误对象调用 `next`。 +如果 `getUserById` 抛出错误或被拒绝(reject),`next` 将会使用抛出的错误或被拒绝的值来调用。如果未提供拒绝值,则会使用 Express 路由内置的默认错误对象调用 `next`。 如果向 `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,17 +131,45 @@ 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 会捕获并处理该错误。 + +你也可以使用处理程序链,将异步代码简化为简单逻辑,从而依靠同步错误捕获机制。举个例子: ```js app.get('/', [ @@ -196,15 +203,48 @@ 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 能够接收到错误。 ## 默认错误处理程序 -Express 内置了错误处理程序,可处理应用中可能出现的所有错误。 这个默认的错误处理中间件函数会被添加到中间件函数栈的末尾。 +Express 内置了错误处理程序,可处理应用中可能出现的所有错误。这个默认的错误处理中间件函数会被添加到中间件函数栈的末尾。 -如果你将错误传递给 `next()`,但未在自定义错误处理程序中处理它,该错误将由内置错误处理程序处理;错误信息和堆栈追踪信息会被返回给客户端。 生产环境中不会包含堆栈追踪信息。 +如果你将错误传递给 `next()`,但未在自定义错误处理程序中处理它,该错误将由内置错误处理程序处理;错误信息和堆栈追踪信息会被返回给客户端。生产环境中不会包含堆栈追踪信息。 @@ -214,7 +254,7 @@ Express 内置了错误处理程序,可处理应用中可能出现的所有错 当错误信息被输出时,响应中会附加以下信息: -- `res.statusCode` 会从 `err.status`(或 `err.statusCode`)中获取设置。 如果该值不在 4xx 或 5xx 范围内,则会被设置为 500。 +- `res.statusCode` 会从 `err.status`(或 `err.statusCode`)中获取设置。如果该值不在 4xx 或 5xx 范围内,则会被设置为 500。 - `res.statusMessage` 会根据状态码自动设置。 - 生产环境中,响应主体会展示状态码信息的 HTML 页面;其他环境下则会展示 `err.stack` 堆栈信息。 - `err.headers` 对象中定义的所有响应头。 @@ -252,7 +292,7 @@ Other error handling middleware can be found at [Express middleware](/resources/ ## 编写错误处理程序 错误处理中间件函数的定义方式与其他中间件函数基本相同,区别在于错误处理函数包含四个参数而非三个: -`(err, req, res, next)`。 举个例子: +`(err, req, res, next)`。举个例子: ```js app.use((err, req, res, next) => { @@ -323,7 +363,7 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => { 中间件函数内的响应可以是任意格式,例如 HTML 错误页面、简单消息或 JSON 字符串。 -出于组织结构(以及高级框架)的目的,你可以定义多个错误处理中间件函数,这与你使用常规中间件函数的方式非常相似。 例如,为使用 `XHR` 发起的请求和未使用 `XHR` 发起的请求分别定义错误处理程序: +出于组织结构(以及高级框架)的目的,你可以定义多个错误处理中间件函数,这与你使用常规中间件函数的方式非常相似。例如,为使用 `XHR` 发起的请求和未使用 `XHR` 发起的请求分别定义错误处理程序: ```cjs title="index.cjs" const bodyParser = require('body-parser'); @@ -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..36e1762355 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,12 +5,12 @@ 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`。 -修改全局原型会影响同一进程中所有已加载的 Express 应用。 如果需要,你可以在创建新应用后仅修改应用专属原型,从而实现仅针对当前应用的修改。 +修改全局原型会影响同一进程中所有已加载的 Express 应用。如果需要,你可以在创建新应用后仅修改应用专属原型,从而实现仅针对当前应用的修改。 ## 方法 @@ -46,7 +46,7 @@ app.response.sendStatus = function ( } as Response['sendStatus']; ``` -上述实现彻底更改了`res.sendStatus`原本的方法签名。 该方法现在可接收状态码、编码类型以及要发送给客户端的消息。 +上述实现彻底更改了`res.sendStatus`原本的方法签名。该方法现在可接收状态码、编码类型以及要发送给客户端的消息。 In TypeScript, augmenting `express-serve-static-core` adds the new overload to the `Response` type so call sites such as `res.sendStatus(404, 'application/json', body)` type-check. The assignment is cast with `as Response['sendStatus']` because replacing a method with a different signature cannot be checked against the original declaration. @@ -67,7 +67,7 @@ Express API 中的属性分为两类: 第二类属性可通过 Express API 扩展接口进行重写。 -以下代码重写了`req.ip`值的获取方式。 现在,它仅返回 `Client-IP` 请求头的值。 +以下代码重写了`req.ip`值的获取方式。现在,它仅返回 `Client-IP` 请求头的值。 ```js Object.defineProperty(app.request, 'ip', { @@ -158,9 +158,9 @@ signature, because the method did not previously exist on the type. ## Prototype -为了提供 Express API,传递给 Express 的请求/响应对象(例如通过 `app(req, res)`)需要继承自相同的原型链。 默认情况下,请求对象继承自 `http.IncomingRequest.prototype`,响应对象继承自 `http.ServerResponse.prototype`。 +为了提供 Express API,传递给 Express 的请求/响应对象(例如通过 `app(req, res)`)需要继承自相同的原型链。默认情况下,请求对象继承自 `http.IncomingRequest.prototype`,响应对象继承自 `http.ServerResponse.prototype`。 -除非必要,否则建议仅在应用层面执行此操作,而非全局层面。 此外,请注意所使用的原型需尽可能与默认原型的功能保持一致。 +除非必要,否则建议仅在应用层面执行此操作,而非全局层面。此外,请注意所使用的原型需尽可能与默认原型的功能保持一致。 ```js // Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse diff --git a/src/content/docs/zh-cn/5x/guide/routing.mdx b/src/content/docs/zh-cn/5x/guide/routing.mdx index 4e27176f19..5dc2642b7d 100644 --- a/src/content/docs/zh-cn/5x/guide/routing.mdx +++ b/src/content/docs/zh-cn/5x/guide/routing.mdx @@ -7,15 +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 +85,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 +111,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,83 +157,15 @@ 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). 如有需要,可使用`\`对其进行转义。 ### Regular expressions -你也可以将正则表达式用作路由路径。 当你需要更复杂的匹配逻辑时,这种方式十分实用。 +你也可以将正则表达式用作路由路径。当你需要更复杂的匹配逻辑时,这种方式十分实用。 ```js // Matches any path containing "a" @@ -258,7 +195,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 +233,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 +253,118 @@ 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 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) => { @@ -332,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'; @@ -354,15 +399,15 @@ 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 +417,7 @@ app.get('/example/a', (req: Request, res: Response) => { }); ``` -多个回调函数可以处理同一个路由(请确保你指定了 `next` 对象)。 举个例子: +多个回调函数可以处理同一个路由(请确保你指定了 `next` 对象)。举个例子: ```js app.get( @@ -402,7 +447,7 @@ app.get( ); ``` -一个回调函数数组可以处理一个路由。 举个例子: +一个回调函数数组可以处理一个路由。举个例子: ```js const cb0 = function (req, res, next) { @@ -442,7 +487,7 @@ const cb2 = function (req: Request, res: Response) { app.get('/example/c', [cb0, cb1, cb2]); ``` -独立函数与函数数组组合使用即可处理一个路由。 举个例子: +独立函数与函数数组组合使用即可处理一个路由。举个例子: ```js const cb0 = function (req, res, next) { @@ -496,26 +541,32 @@ 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 | 描述 | -| ----------------------------------------------- | ---------------------------------------------------- | -| [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()` 为路由路径创建可链式调用的路由处理程序。你可以使用 `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()` 定义的链式路由处理程序示例。```js +app +.route('/book') +.get((req, res) => { +res.send('Ge -以下是使用 `app.route()` 定义的链式路由处理程序示例。 +```` ```js app @@ -529,7 +580,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -549,9 +600,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 +695,10 @@ 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 }); -``` +```` 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..73622767fd 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) => { }); ``` -该示例展示了一条路由及其处理函数(中间件体系)。 该函数处理指向 `/user/:id` 路径的 GET 请求。 +### 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` 对象会被解析为常规中间件,从而无法处理错误。 -## 内置中间件 + + + + +For more information, see the [Error handling](/guide/error-handling) guide. -从 4.x 版本开始,Express 不再依赖 [Connect](https://github.com/senchalabs/connect)。 之前包含在 Express 中的中间件函数,现在已经拆分到独立的模块中;查看[中间件函数列表](https://github.com/senchalabs/connect#middleware)。 + + +## 内置中间件 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..ca5de7ac37 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,23 +1,21 @@ --- 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'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -模板引擎能够让你在应用中使用静态模板文件。 运行时,模板引擎会将模板文件中的变量替换为实际值,并把模板转换成HTML文件发送至客户端。 -这种方式能够简化HTML页面的开发。 +模板引擎能够让你在应用中使用静态模板文件。运行时,模板引擎会将模板文件中的变量替换为实际值,并把模板转换成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')`。 +- `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 +23,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. @@ -45,7 +44,7 @@ html h1= message ``` -创建一条路由来渲染`index.pug`文件。 如果未配置`view engine`属性,则必须指明视图文件的后缀名。 否则可以省略文件后缀。 +创建一条路由来渲染`index.pug`文件。如果未配置`view engine`属性,则必须指明视图文件的后缀名。否则可以省略文件后缀。 ```js app.get('/', (req, res) => { @@ -63,4 +62,4 @@ app.get('/', (req: Request, res: Response) => { 当访问首页时,`index.pug` 文件会被渲染成 HTML。 -视图引擎缓存不会缓存模板渲染后的输出内容,仅缓存原始模板文件本身。 即便开启缓存,每次请求视图仍会重新渲染。 +视图引擎缓存不会缓存模板渲染后的输出内容,仅缓存原始模板文件本身。即便开启缓存,每次请求视图仍会重新渲染。 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..576c5f1686 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 路由器中的一个函数,调用该函数时,会执行当前中间件之后的下一个中间件。 @@ -14,7 +15,7 @@ _Middleware_ functions are functions that have access to the [request object](/a - 终止请求-响应周期。 - 调用堆栈中的下一个中间件。 -如果当前中间件函数没有终止请求-响应周期,它必须调用 `next()` 以将控制权传递给下一个中间件函数。 否则,请求将会被挂起。 +如果当前中间件函数没有终止请求-响应周期,它必须调用 `next()` 以将控制权传递给下一个中间件函数。否则,请求将会被挂起。 下图展示了中间件函数调用的组成要素: @@ -24,8 +25,7 @@ _Middleware_ functions are functions that have access to the [request object](/a ## 示例 -以下是一个简单的 Express “Hello World” 应用示例。 -本文的后续部分将为该应用定义并添加三个中间件函数: +以下是一个简单的 Express “Hello World” 应用示例。本文的后续部分将为该应用定义并添加三个中间件函数: 一个名为 `myLogger`,用于打印简单的日志信息;一个名为 `requestTime`,用于显示 HTTP 请求的时间戳;还有一个名为 `validateCookies`,用于验证传入的 Cookie。 ```cjs title="index.cjs" @@ -65,7 +65,7 @@ app.listen(3000); ### 中间件函数 myLogger -以下是一个名为 `myLogger` 的简单中间件函数示例。 当对应用的请求经过该函数时,它只会打印 "LOGGED"。 该中间件函数被赋值给了一个名为 `myLogger` 的变量。 +以下是一个名为 `myLogger` 的简单中间件函数示例。当对应用的请求经过该函数时,它只会打印 "LOGGED"。该中间件函数被赋值给了一个名为 `myLogger` 的变量。 ```js const myLogger = function (req, res, next) { @@ -91,12 +91,11 @@ needed. -注意上述代码中对 `next()` 的调用。 调用该函数会执行应用中的下一个中间件函数。 `next()` 函数并非 Node.js 或 Express API 的一部分,而是传递给中间件函数的第三个参数。 `next()` 函数可以被命名为任意名称,但按照惯例,它始终被命名为 `next`。 为避免混淆,请始终遵循此命名惯例。 +注意上述代码中对 `next()` 的调用。调用该函数会执行应用中的下一个中间件函数。 `next()` 函数并非 Node.js 或 Express API 的一部分,而是传递给中间件函数的第三个参数。 `next()` 函数可以被命名为任意名称,但按照惯例,它始终被命名为 `next`。为避免混淆,请始终遵循此命名惯例。 -加载中间件函数时,需调用 `app.use()` 并传入该中间件函数。 -例如,以下代码在根路径(/)路由之前加载 `myLogger` 中间件函数。 +加载中间件函数时,需调用 `app.use()` 并传入该中间件函数。例如,以下代码在根路径(/)路由之前加载 `myLogger` 中间件函数。 ```cjs title="index.cjs" const express = require('express'); @@ -164,7 +163,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). @@ -208,7 +208,7 @@ const requestTime = function (req: Request, res: Response, next: NextFunction) { }; ``` -该应用现在使用了 `requestTime` 中间件函数。 此外,根路径路由的回调函数使用了中间件函数挂载到`req`(请求对象)上的属性。 +该应用现在使用了 `requestTime` 中间件函数。此外,根路径路由的回调函数使用了中间件函数挂载到`req`(请求对象)上的属性。 ```cjs title="index.cjs" const express = require('express'); @@ -376,13 +376,17 @@ app.listen(3000); -注意 `next()` 是在 `await cookieValidator(req.cookies)` 之后调用的。 这能确保如果 `cookieValidator` 状态变为已兑现,堆栈中的下一个中间件将会被调用。 如果你向 `next()` 函数传入任何内容(字符串 `'route'` 或 `'router'` 除外),Express 会将当前请求视为错误,并跳过所有剩余的非错误处理路由和中间件函数。 +注意 `next()` 是在 `await cookieValidator(req.cookies)` 之后调用的。这能确保如果 `cookieValidator` 状态变为已兑现,堆栈中的下一个中间件将会被调用。如果你向 `next()` 函数传入任何内容(字符串 `'route'` 或 `'router'` 除外),Express 会将当前请求视为错误,并跳过所有剩余的非错误处理路由和中间件函数。 -由于你可以访问请求对象、响应对象、堆栈中的下一个中间件函数以及整个 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/examples.mdx b/src/content/docs/zh-cn/5x/starter/examples.mdx index 5e731014f9..4b6a32ed4e 100644 --- a/src/content/docs/zh-cn/5x/starter/examples.mdx +++ b/src/content/docs/zh-cn/5x/starter/examples.mdx @@ -39,7 +39,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; -这些信息指的是第三方站点、产品或模块,它们不是由Expressjs团队维护的。 此处的罗列并不代表 Express 项目团队的认可或推荐。 +这些信息指的是第三方站点、产品或模块,它们不是由Expressjs团队维护的。此处的罗列并不代表 Express 项目团队的认可或推荐。 diff --git a/src/content/docs/zh-cn/5x/starter/faq.mdx b/src/content/docs/zh-cn/5x/starter/faq.mdx index 87140bd6e0..f58637cae4 100644 --- a/src/content/docs/zh-cn/5x/starter/faq.mdx +++ b/src/content/docs/zh-cn/5x/starter/faq.mdx @@ -3,11 +3,13 @@ title: FAQ  常见问题解答 description: 查找有关 Express.js 的常见问题解答,涵盖应用程序架构、数据模型、身份验证、模板引擎、错误处理等相关主题。 --- +import ReadMore from '@components/patterns/ReadMore/ReadMore.astro'; + ## 我应该如何组织我的应用程序? -这个问题没有标准答案。 答案取决于你的应用规模以及参与开发的团队。 为实现最大限度的灵活性,Express 不会对项目结构做任何强制限定。 +这个问题没有标准答案。答案取决于你的应用规模以及参与开发的团队。为实现最大限度的灵活性,Express 不会对项目结构做任何强制限定。 -路由和其他应用专属逻辑可拆分至任意数量文件,并采用你偏好的任意目录结构存放。 可参考下方示例获取项目结构设计思路: +路由和其他应用专属逻辑可拆分至任意数量文件,并采用你偏好的任意目录结构存放。可参考下方示例获取项目结构设计思路: - [Route listings](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-L47) - [Route map](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) @@ -19,25 +21,27 @@ description: 查找有关 Express.js 的常见问题解答,涵盖应用程序 ## 如何定义模型? -Express 本身不包含数据库相关概念。 这一概念交由第三方 Node 模块实现,让你能够与几乎所有数据库进行交互。 +Express 本身不包含数据库相关概念。这一概念交由第三方 Node 模块实现,让你能够与几乎所有数据库进行交互。 See [LoopBack](http://loopback.io) for an Express-based framework that is centered around models. ## 如何实现用户身份验证? -身份验证同样是一项带有主观选型倾向的功能,Express 并未涉足该领域。 你可以选用任意你想要的身份验证方案。 -如需实现简易的用户名/密码验证方案,可参考[该示例](https://github.com/expressjs/express/tree/master/examples/auth)。 +身份验证同样是一项带有主观选型倾向的功能,Express 并未涉足该领域。你可以选用任意你想要的身份验证方案。如需实现简易的用户名/密码验证方案,可参考[该示例](https://github.com/expressjs/express/tree/master/examples/auth)。 ## Express 支持哪些模板引擎? -Express 支持所有符合 `(path, locals, callback)` 入参规范的模板引擎。 -如需统一各类模板引擎的接口与缓存机制,可查看 [consolidate.js](https://github.com/visionmedia/consolidate.js) 项目以获取相关支持。 未列入清单的模板引擎也可能兼容 Express 的调用规范。 +Express 支持所有符合 `(path, locals, callback)` 入参规范的模板引擎。如需统一各类模板引擎的接口与缓存机制,可查看 [consolidate.js](https://github.com/visionmedia/consolidate.js) 项目以获取相关支持。未列入清单的模板引擎也可能兼容 Express 的调用规范。 + + + +For more information, see the [Using template engines with Express](/guide/using-template-engines) guide. -For more information, see [Using template engines with Express](/guide/using-template-engines). + ## 如何处理 404 响应? -在 Express 中,404 响应并非由错误导致,因此错误处理中间件不会捕获这类响应。 出现这种行为的原因是,404 响应仅表示没有其他待执行的操作;换言之,Express 已执行完所有中间件函数和路由,但未找到任何能够响应请求的处理逻辑。 你只需在中间件栈的最底部(所有其他函数之后)添加一个中间件函数来处理 404 响应即可: +在 Express 中,404 响应并非由错误导致,因此错误处理中间件不会捕获这类响应。出现这种行为的原因是,404 响应仅表示没有其他待执行的操作;换言之,Express 已执行完所有中间件函数和路由,但未找到任何能够响应请求的处理逻辑。你只需在中间件栈的最底部(所有其他函数之后)添加一个中间件函数来处理 404 响应即可: ```js app.use((req, res, next) => { @@ -75,13 +79,15 @@ 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? -无需额外操作! 无需使用 `res.render()` 函数来“渲染” HTML。 -如果你需要响应指定的文件,请使用 `res.sendFile()` 函数。 -如果你要从一个目录提供多个静态资源,请使用 `express.static()` 中间件函数。 +无需额外操作!无需使用 `res.render()` 函数来“渲染” HTML。如果你需要响应指定的文件,请使用 `res.sendFile()` 函数。如果你要从一个目录提供多个静态资源,请使用 `express.static()` 中间件函数。 ## Express 需要哪个版本的 Node.js? diff --git a/src/content/docs/zh-cn/5x/starter/generator.mdx b/src/content/docs/zh-cn/5x/starter/generator.mdx index 1bbc4ad151..cc10fe742e 100644 --- a/src/content/docs/zh-cn/5x/starter/generator.mdx +++ b/src/content/docs/zh-cn/5x/starter/generator.mdx @@ -42,7 +42,7 @@ $ express -h -f, --force force on non-empty directory ``` -例如,以下命令会创建一个名为 _myapp_ 的 Express 应用。 此应用将创建在当前工作目录下名为 _myapp_ 的文件夹中,并且视图引擎将设置为 Pug: +例如,以下命令会创建一个名为 _myapp_ 的 Express 应用。此应用将创建在当前工作目录下名为 _myapp_ 的文件夹中,并且视图引擎将设置为 Pug: ```bash $ express --view=pug myapp @@ -119,7 +119,6 @@ PS> $env:DEBUG='myapp:*'; npm start -生成器创建的应用结构只是 Express 应用多种结构方案中的一种。 -你可以随意使用此结构,或根据你的需求对其进行修改。 +生成器创建的应用结构只是 Express 应用多种结构方案中的一种。你可以随意使用此结构,或根据你的需求对其进行修改。 diff --git a/src/content/docs/zh-cn/5x/starter/hello-world.mdx b/src/content/docs/zh-cn/5x/starter/hello-world.mdx index ff31016a60..e26d1fbd42 100644 --- a/src/content/docs/zh-cn/5x/starter/hello-world.mdx +++ b/src/content/docs/zh-cn/5x/starter/hello-world.mdx @@ -7,7 +7,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; -下面展示的是一个本质上最简单的 Express 应用。 这是一个单文件应用—而不是使用 [Express 生成器](/en/starter/generator) 所生成的项目结构,后者会创建一个完整应用的脚手架,包含多个 JavaScript 文件、Jade 模板,以及用于不同用途的子目录。 +下面展示的是一个本质上最简单的 Express 应用。这是一个单文件应用—而不是使用 [Express 生成器](/en/starter/generator) 所生成的项目结构,后者会创建一个完整应用的脚手架,包含多个 JavaScript 文件、Jade 模板,以及用于不同用途的子目录。 @@ -55,7 +55,7 @@ app.listen(port, () => { }); ``` -该应用启动一个服务器,并在 3000 端口监听连接请求。 当请求根 URL(`/`)或“ _route_”时,该应用会返回“Hello World!”。 对于其他所有路径,它都会返回 **404 Not Found**。 +该应用启动一个服务器,并在 3000 端口监听连接请求。当请求根 URL(`/`)或“ _route_”时,该应用会返回“Hello World!”。对于其他所有路径,它都会返回 **404 Not Found**。 ## 本地运行 diff --git a/src/content/docs/zh-cn/5x/starter/installing.mdx b/src/content/docs/zh-cn/5x/starter/installing.mdx index d73ef7b75a..0becf17ca7 100644 --- a/src/content/docs/zh-cn/5x/starter/installing.mdx +++ b/src/content/docs/zh-cn/5x/starter/installing.mdx @@ -6,28 +6,26 @@ description: Learn how to install Express.js in your Node.js environment, includ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -在开始前,请确保你有安装 [Node.js](https://nodejs.org/) 18 或更高版本。 然后,为你的应用创建一个目录并进入该目录。 +在开始前,请确保你有安装 [Node.js](https://nodejs.org/) 18 或更高版本。然后,为你的应用创建一个目录并进入该目录。 ```bash mkdir myapp cd myapp ``` -使用 `npm init` 命令为你的应用创建一个 `package.json` 文件。 -有关 `package.json` 工作机制的更多信息,请参阅 [npm 的 package.json 处理细则](https://docs.npmjs.com/files/package.json)。 +使用 `npm init` 命令为你的应用创建一个 `package.json` 文件。有关 `package.json` 工作机制的更多信息,请参阅 [npm 的 package.json 处理细则](https://docs.npmjs.com/files/package.json)。 -该命令会提示你输入一些信息,例如应用的名称和版本号。 -目前,你可以直接按回车键接受大多数默认值,但以下情况除外: +该命令会提示你输入一些信息,例如应用的名称和版本号。目前,你可以直接按回车键接受大多数默认值,但以下情况除外: ``` entry point: (index.js) ``` -输入 `app.js`,或者你希望作为主文件的其他名称。 如果希望使用 `index.js`,直接按回车键接受系统建议的默认文件名即可。 +输入 `app.js`,或者你希望作为主文件的其他名称。如果希望使用 `index.js`,直接按回车键接受系统建议的默认文件名即可。 -现在,在 `myapp` 目录中安装 Express,并将其保存到依赖列表中。 举个例子: +现在,在 `myapp` 目录中安装 Express,并将其保存到依赖列表中。举个例子: @@ -70,7 +68,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..6ed70d9d41 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` 中间件函数。 @@ -71,7 +72,7 @@ http://localhost:3000/static/images/bg.png http://localhost:3000/static/hello.html ``` -但是,你提供给 `express.static` 函数的路径是相对于你启动 `node` 进程的目录而言的。 如果你从其他目录启动 Express 应用,使用你要托管的目录的绝对路径会更安全: +但是,你提供给 `express.static` 函数的路径是相对于你启动 `node` 进程的目录而言的。如果你从其他目录启动 Express 应用,使用你要托管的目录的绝对路径会更安全: ```cjs title="index.cjs" const path = require('path'); @@ -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..ee8c9bffc8 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 | | ----------------------------------------------- | ------------------------------------------------------------------------------------- | @@ -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..7873cf5cc3 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 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,26 @@ 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 | -| ----------------------------------------------- | ------------------------------------------------------------------------------------- | -| [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 using `app.route()`. +|## app.route()You can create chainable route handlers for a rou ```js app @@ -530,7 +576,7 @@ app .put((req, res) => { res.send('Update the book'); }); -``` +```` ```ts import { type Request, type Response } from 'express'; @@ -550,9 +596,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 +691,10 @@ 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 }); -``` +```` 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 0d29a71ee9..46d62a5d53 100644 --- a/src/content/pages/de/advanced/best-practice-security.mdx +++ b/src/content/pages/de/advanced/best-practice-security.mdx @@ -48,7 +48,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) { @@ -296,6 +296,6 @@ Hier sind einige weitere Empfehlungen der ausgezeichneten [Node.js Security Chec - Verteidigen Sie gegen SQL-Injektionsangriffe durch parametrierte Abfragen oder vorbereitete Anweisungen. - Benutzen Sie das Open-Source [sqlmap](http://sqlmap.org/) Werkzeug, um Verwundbarkeiten in Ihrer App zu erkennen. - Verwenden Sie die Werkzeuge [nmap](https://nmap.org/) und [sslyze](https://github.com/nabla-c0d3/sslyze) um die Konfiguration Ihrer SSL-Chiffren zu testen, Schlüssel, Neuverhandlung sowie die Gültigkeit Ihres Zertifikats. -- Verwende [safe-regex](https://www.npmjs.com/package/safe-regex), um sicherzustellen, dass deine regulären Ausdrücke nicht anfällig für [reguläre Ausdrucksverweigerung des Dienstes](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) Angriffe sind. +- Verwende [safe-regex](https://www.npmjs.com/package/safe-regex), um sicherzustellen, dass deine regulären Ausdrücke nicht anfällig für [reguläre Ausdrucksverweigerung des Dienstes](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) Angriffe sind. [helmet]: https://helmetjs.github.io/ 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/guide/migrating-4.mdx b/src/content/pages/de/guide/migrating-4.mdx index d3fe3b87ca..4e45c1793d 100644 --- a/src/content/pages/de/guide/migrating-4.mdx +++ b/src/content/pages/de/guide/migrating-4.mdx @@ -43,133 +43,23 @@ Middleware hinzufügen, die für den Betrieb Ihrer App erforderlich ist. Folgen Die folgende Tabelle listet Express 3 Middleware und ihre Amtskollegen in Express 4 auf. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Express 3Express 4
- express.bodyParser - - Körper-Parser + - Multer -
- express .compress - - Komprimierung -
- express.cookieSession - - Cookie-Sitzung -
- express.cookieParser - - Cookie-Parser -
- express.logger - - Morgan -
- express.session - - Express-Session -
- express.favicon - - Servierfavicon -
- express.responseTime - - Antwortzeit -
- express.errorHandler - - errorhandler -
- express.methodOverride - - Methodenüberschreibung -
- express.timeout - - Verbindungs-Timeout -
- express.vhost - - vhost -
- express.csrf - - csurf -
- express.directory - - Servierindex -
- express.static - - Servierstatische -
+| Express 3 | Express 4 | +| ------------------------ | ------------------------------------------------------------------------------------------------------- | +| `express.bodyParser` | [body-parser](https://github.com/expressjs/body-parser) + [multer](https://github.com/expressjs/multer) | +| `express.compress` | [compression](https://github.com/expressjs/compression) | +| `express.cookieSession` | [cookie-session](https://github.com/expressjs/cookie-session) | +| `express.cookieParser` | [cookie-parser](https://github.com/expressjs/cookie-parser) | +| `express.logger` | [morgan](https://github.com/expressjs/morgan) | +| `express.session` | [express-session](https://github.com/expressjs/session) | +| `express.favicon` | [serve-favicon](https://github.com/expressjs/serve-favicon) | +| `express.responseTime` | [response-time](https://github.com/expressjs/response-time) | +| `express.errorHandler` | [errorhandler](https://github.com/expressjs/errorhandler) | +| `express.methodOverride` | [method-override](https://github.com/expressjs/method-override) | +| `express.timeout` | [connect-timeout](https://github.com/expressjs/timeout) | +| `express.vhost` | [vhost](https://github.com/expressjs/vhost) | +| `express.csrf` | [csurf](https://github.com/expressjs/csurf) | +| `express.directory` | [serve-index](https://github.com/expressjs/serve-index) | +| `express.static` | [serve-static](https://github.com/expressjs/serve-static) | Hier ist die [vollständige Liste](https://github.com/senchalabs/connect#middleware) von Express 4 Middleware. @@ -305,78 +195,21 @@ Middleware auf, die spezifisch für die Route ist. Die folgende Tabelle listet weitere kleine, aber wichtige Änderungen in Express 4 auf: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ObjektBeschreibung
Node.jsExpress 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x.
`http.createServer()` - Das `http` Modul wird nicht mehr benötigt, außer du musst direkt mit ihm - (socket.io/SPDY/HTTPS) arbeiten. The app can be started by using the `app.listen()` function. -
`app.configure()` - Die Funktion `app.configure()` wurde entfernt. Use the `process.env.NODE_ENV` or - `app.get('env')` function to detect the environment and configure the app accordingly. -
`json spaces` - The `json spaces` application property is disabled by default in Express 4. -
`req.accepted()` - Benutze `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()` und - `req.acceptsLanguages()`. -
`res.location()`Es werden keine relativen URLs mehr aufgelöst.
`req.params`War ein Array; jetzt ein Objekt.
`res.locals`War eine Funktion; jetzt ein Objekt.
`res.headerSent`In `res.headersSent` geändert.
`app.route`Jetzt als `app.mountpath` verfügbar.
`res.on('header')`Entfernt.
`res.charset`Entfernt.
`res.setHeader('Set-Cookie', val)` - Die Funktionalität ist nun auf das Setzen des grundlegenden Cookie-Wertes beschränkt. Benutze - `res.cookie()` für hinzugefügte Funktionalität. -
+| Object | Beschreibung | +| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Node.js | Express 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x. | +| `http.createServer()` | The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). The app can be started by using the `app.listen()` function. | +| `app.configure()` | Die Funktion `app.configure()` wurde entfernt. Use the `process.env.NODE_ENV` or `app.get('env')` function to detect the environment and configure the app accordingly. | +| `json spaces` | The `json spaces` application property is disabled by default in Express 4. | +| `req.accepted()` | Benutze `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()` und `req.acceptsLanguages()`. | +| `res.location()` | No longer resolves relative URLs. | +| `req.params` | Was an array; now an object. | +| `res.locals` | Was a function; now an object. | +| `res.headerSent` | Changed to `res.headersSent`. | +| `app.route` | Now available as `app.mountpath`. | +| `res.on('header')` | Removed. | +| `res.charset` | Removed. | +| `res.setHeader('Set-Cookie', val)` | Die Funktionalität ist nun auf das Setzen des grundlegenden Cookie-Wertes beschränkt. Use `res.cookie()` for added functionality. | ## Beispiel-App-Migration diff --git a/src/content/pages/de/resources/middleware/body-parser.mdx b/src/content/pages/de/resources/middleware/body-parser.mdx index 0dcfdf32a2..0eb696049e 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. @@ -44,6 +44,10 @@ Dieses Modul bietet folgende Parser: - [Text Körper Parser](#bodyparsertextoptions) - [URL-kodierter Form-Body Parser](#bodyparserurlencodedoptions) +All parsers support automatic inflation of `gzip`, `br` (brotli), `deflate` +and `zstd` encodings. `zstd` is available in Node.js `^22.15.0` and +`>=23.8.0`. + Andere Körper-Parser, die Sie interessieren können: - [body](https://www.npmjs.com/package/body#readme) @@ -84,9 +88,8 @@ Die verschiedenen Fehler, die von diesem Modul zurückgegeben werden, werden im ### bodyParser.json([options]) Gibt Middleware zurück, die nur `json` analysiert und nur Anfragen ansieht, bei denen -der `Content-Type` Header mit der `type` Option übereinstimmt. Dieser Parser akzeptiert jede -Unicode-Kodierung des Körpers und unterstützt die automatische Inflation von `gzip`, -`br` (brotli) und `deflate` Kodierungen. +der `Content-Type` Header mit der `type` Option übereinstimmt. This parser accepts any +Unicode encoding of the body. Ein neues `body` Objekt mit den geparsten Daten wird auf dem `request` Objekt nach der Middleware (d.h. `req.body`) gefüllt. @@ -96,22 +99,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 +124,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 +140,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 @@ -146,9 +149,7 @@ Kodierung der Anfrage. Das Parsen kann durch Werfen eines Fehlers abgebrochen we ### bodyParser.raw([options]) Gibt Middleware zurück, die alle Körper als `Buffer` parst und nur -Anfragen ansieht, wo der `Content-Type` Header mit der `type` Option übereinstimmt. Dieser -Parser unterstützt die automatische Inflation von `gzip`, `br` (brotli) und `deflate` -Kodierungen. +Anfragen ansieht, wo der `Content-Type` Header mit der `type` Option übereinstimmt. Ein neues `body` Objekt mit den geparsten Daten wird auf dem `request` Objekt nach der Middleware (d.h. `req.body`) gefüllt. Dies wird ein `Buffer` Objekt @@ -159,21 +160,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 +186,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 @@ -194,50 +195,48 @@ Kodierung der Anfrage. Das Parsen kann durch Werfen eines Fehlers abgebrochen we ### bodyParser.text([options]) Gibt Middleware zurück, die alle Körper als String parst und nur -Anfragen ansieht, in denen der `Content-Type` Header mit der `type` Option übereinstimmt. Dieser -Parser unterstützt die automatische Inflation von `gzip`, `br` (brotli) und `deflate` -Kodierungen. +Anfragen ansieht, in denen der `Content-Type` Header mit der `type` Option übereinstimmt. -Ein neuer `body` String, der die geparsten Daten enthält, wird auf dem `request` -Objekt nach der Middleware (d.h. `req.body`) gefüllt. Dies wird eine Zeichenkette des -Körpers sein. +A new `body` string containing the parsed data is populated on the `request` +object after the middleware (i.e. `req.body`). This will be a string of the +body. #### Optionen 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`. +Specify the default character set for the text content if the charset is not +specified in the `Content-Type` header of the request. 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 -eine Funktion, Die Option `type` wird direkt an die -[type-is](https://www.npmjs.com/package/type-is#readme) übergeben und kann -ein Name der Erweiterung sein (wie `txt`), ein Mime-Typ (wie `text/plain`), oder ein Mime -tippen Sie mit einem Platzhalter (wie `*/*` oder `text/*`). Wenn eine Funktion, wird die `type` -Option als `fn(req)` aufgerufen und die Anfrage geparst, wenn sie einen -truthy Wert zurückgibt. Standard ist `text/plain`. +parst. Diese Option kann ein String, ein Array von Strings oder eine Funktion sein. If not +a function, `type` option is passed directly to the +[type-is](https://www.npmjs.com/package/type-is#readme) library and this can +be an extension name (like `txt`), a mime type (like `text/plain`), or a mime +type with a wildcard (like `*/*` or `text/*`). If a function, the `type` +option is called as `fn(req)` and the request is parsed if it returns a +truthy value. Defaults to `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 @@ -245,195 +244,194 @@ Kodierung der Anfrage. Das Parsen kann durch Werfen eines Fehlers abgebrochen we ### bodyParser.urlencoded([options]) -Gibt Middleware zurück, die nur `urlencoded` Körper analysiert und nur -Anfragen ansieht, in denen der `Content-Type` Header mit der `type` Option übereinstimmt. Dieser -Parser akzeptiert nur UTF-8 und ISO-8859-1 Kodierungen des Körpers und unterstützt -automatische Inflation von `gzip`, `br` (brotli) und `deflate` Kodierungen. +Returns middleware that only parses `urlencoded` bodies and only looks at +requests where the `Content-Type` header matches the `type` option. This +parser accepts only UTF-8 and ISO-8859-1 encodings of the body. Ein neues `body` Objekt mit den geparsten Daten wird auf dem `request` -Objekt nach der Middleware (d.h. `req.body`) gefüllt. Dieses Objekt wird Paare mit Schlüsselwert -enthalten, wobei der Wert ein String oder ein Array sein kann (wenn `extended` -`false` ist), oder jeder beliebige Typ (wenn `extended` `true` ist). +Objekt nach der Middleware (d.h. `req.body`) gefüllt. This object will contain +key-value pairs, where the value can be a string or array (when `extended` is +`false`), or any type (when `extended` is `true`). #### Optionen 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 +The "extended" syntax allows for rich objects and arrays to be encoded into the +URL-encoded format, allowing for a JSON-like experience with URL-encoded. For more information, please see the qs library. -Standard ist `false`. +Defaults to `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. ##### parameterLimit -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`. +The `parameterLimit` option controls the maximum number of parameters that +are allowed in the URL-encoded data. If a request contains more parameters +than this value, a 413 will be returned to the client. Defaults to `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 -eine Funktion, Die Option `type` wird direkt an die -[type-is](https://www.npmjs.com/package/type-is#readme) übergeben und kann -ein Name der Erweiterung sein (wie `urlencoded`), ein Mime-Typ (wie -`application/x-www-form-urlencoded`), oder ein Mime-Typ mit einem Platzhalter (wie -`*/x-www-form-urlencoded`). Wenn eine Funktion aufgerufen wird, wird die `type` Option als -`fn(req)` aufgerufen und die Anfrage wird geparst, wenn sie einen truthy-Wert zurückgibt. Standardmäßig -auf `application/x-www-form-urlencoded`. +parst. Diese Option kann ein String, ein Array von Strings oder eine Funktion sein. If not +a function, `type` option is passed directly to the +[type-is](https://www.npmjs.com/package/type-is#readme) library and this can +be an extension name (like `urlencoded`), a mime type (like +`application/x-www-form-urlencoded`), or a mime type with a wildcard (like +`*/x-www-form-urlencoded`). If a function, the `type` option is called as +`fn(req)` and the request is parsed if it returns a truthy value. Defaults +to `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`. +The default charset to parse as, if not specified in content-type. Must be +either `utf-8` or `iso-8859-1`. Standard ist `utf-8`. ##### charsetSentinel -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`. +Whether to let the value of the `utf8` parameter take precedence as the charset +selector. It requires the form to contain a parameter named `utf8` with a value +of `✓`. Defaults to `false`. -##### interpretieren NumericEntities +##### interpretNumericEntities -Gibt an, ob numerische Entitäten wie `☺` beim Parsen eines iso-8859-1 -dekodiert werden sollen. Standard ist `false`. +Whether to decode numeric entities such as `☺` when parsing an iso-8859-1 +form. Defaults to `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. +The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible. -## Fehler +## Errors -Die von diesem Modul bereitgestellten Middlewares erzeugen Fehler mit Hilfe des -[`http-errors` Modul](https://www.npmjs.com/package/http-errors). Die Fehler -werden typischerweise eine Eigenschaft `status`/`statusCode` haben, die den vorgeschlagenen -HTTP-Antwortcode enthält eine `expose` Eigenschaft um festzustellen, ob die `message` Eigenschaft -dem Client angezeigt werden soll, eine Eigenschaft `type` um den Typ des -Fehlers zu ermitteln, ohne mit der `message` übereinzustimmen, und eine `body`-Eigenschaft mit -des gelesenen Textes, falls verfügbar. +The middlewares provided by this module create errors using the +[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors +will typically have a `status`/`statusCode` property that contains the suggested +HTTP response code, an `expose` property to determine if the `message` property +should be displayed to the client, a `type` property to determine the type of +error without matching against the `message`, and a `body` property containing +the read body, if available. -Die folgenden sind die häufigen Fehler erzeugt, obwohl jeder Fehler aus verschiedenen Gründen durch -kommen kann. +The following are the common errors created, though any error can come through +for various reasons. -### 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 +This error will occur when the request had a `Content-Encoding` header that +contained an encoding but the "inflation" option was set to `false`. 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 +This error will occur when the request contained an entity that could not be +verified by the defined `verify` option. Die Eigenschaft `status` ist +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 +This error will occur when the request is aborted by the client before reading +the body has finished. 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. +This error will occur when the request body's size is larger than the "limit" +option. The `limit` property will be set to the byte limit and the `length` +property will be set to the request body's length. Die Eigenschaft `status` ist +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. +This error will occur when the request's length did not match the length from +the `Content-Length` header. This typically occurs when the request is malformed, +typically when the `Content-Length` header was calculated based on characters +instead of bytes. Die Eigenschaft `status` ist auf `400` gesetzt und die Eigenschaft `type` +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. +This error will occur when something called the `req.setEncoding` method prior +to this middleware. This module operates directly on bytes only and you cannot +call `req.setEncoding` when using this module. Die Eigenschaft `status` ist auf +`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. +This error will occur when the request is no longer readable when this middleware +attempts to read it. This typically means something other than a middleware from +this module read the request body already and the middleware was also configured to +read the same request. Die Eigenschaft `status` ist auf `500` gesetzt und die Eigenschaft `type` +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. +This error will occur when the content of the request exceeds the configured +`parameterLimit` for the `urlencoded` parser. Die Eigenschaft `status` ist auf +`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` +This error will occur when the request had a charset parameter in the +`Content-Type` header, but the `iconv-lite` module does not support it OR the +parser does not support it. The charset is contained in the message as well +as in the `charset` property. Die Eigenschaft `status` ist auf `415` gesetzt, die Eigenschaft +`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` +This error will occur when the request had a `Content-Encoding` header that +contained an unsupported encoding. The encoding is contained in the message +as well as in the `encoding` property. Die Eigenschaft `status` ist auf `415` gesetzt, +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 +### The input exceeded the depth -Dieser Fehler tritt auf, wenn `bodyParser.urlencoded` mit der Eigenschaft `extended` auf `true` gesetzt wird und die Eingabe die konfigurierte Option `depth` überschreitet. Die Eigenschaft `status` ist auf `400` gesetzt. Es wird empfohlen, die `depth` Option zu überprüfen und auszuwerten, wenn ein höherer Wert erforderlich ist. Wenn die Option `depth` auf `32` gesetzt ist (Standardwert) wird der Fehler nicht angezeigt. +This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown. ## Beispiele -### Ausdrücken/Verbinden auf oberster Ebene generisch +### Express/Connect top-level generic This example demonstrates adding a generic JSON and URL-encoded parser as a top-level middleware, which will parse the bodies of all incoming requests. -Dies ist die einfachste Einrichtung. +This is the simplest setup. ```js const express = require('express'); @@ -454,11 +452,11 @@ app.use(function (req, res) { }); ``` -### Express-Route-spezifisch +### Express route-specific -Dieses Beispiel zeigt das Hinzufügen von Körper-Parsern zu den Routen, die -benötigt. Im Allgemeinen ist dies der am meisten empfohlene Weg, Körper-Parser mit -Express zu verwenden. +This example demonstrates adding body parsers specifically to the routes that +need them. In general, this is the most recommended way to use body-parser with +Express. ```js const express = require('express'); @@ -485,10 +483,10 @@ app.post('/api/users', jsonParser, function (req, res) { }); ``` -### Akzeptierten Typ für Parser ändern +### Change accepted type for parsers -Alle Parser akzeptieren eine `type`-Option, mit der du die -`Content-Type` ändern kannst, die die Middleware parsen wird. +All the parsers accept a `type` option which allows you to change the +`Content-Type` that the middleware will parse. ```js const express = require('express'); @@ -511,5 +509,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..f096d835ac 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 --- @@ -8,8 +8,8 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -21,13 +21,13 @@ Folgende Kompressionscodierungen werden unterstützt: - gzip - br (brotli) -**Notiz** Brotli wird nur seit Node.js Versionen v11.7.0 und v10.16.0. +**Note** Brotli is available in all currently supported Node.js LTS versions (v18+). ## Installieren Dies ist ein [Node.js](https://nodejs.org/en/) Modul über die [npm Registry](https://www.npmjs.com/). Installation erfolgt mit dem -[`npm install` Befehl](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): +[`npm install` Befehl](https://docs.npmjs.com/downloading-and-installing-packages-locally): @@ -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. @@ -304,7 +304,7 @@ Das Projekt Express.js begrüßt alle konstruktiven Beiträge. Beiträge nehmen vom Code für Fehlerbehebungen und -erweiterungen, über Ergänzungen und Korrekturen bis hin zur Dokumentation, zusätzliche Tests, Triaging incoming Pull-Requests und Issues und mehr! -Siehe [Mitwirkende Anleitung](https://github.com/expressjs/express/blob/master/Contributing.md) für weitere technische Details zum Beitragen. +See the [Contributing Guide](https://github.com/expressjs/.github/blob/HEAD/CONTRIBUTING.md) for more technical details on contributing. ## Lizenz @@ -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..0b80e37b75 100644 --- a/src/content/pages/de/resources/middleware/morgan.mdx +++ b/src/content/pages/de/resources/middleware/morgan.mdx @@ -8,14 +8,14 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; HTTP Request Logger Middleware für node.js -> Benannt nach [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), eine Sendung, die du nicht sehen solltest bis zum Ende beobachten solltest. +> Named after [Dexter](https://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. ## Installation @@ -35,13 +35,23 @@ Dies ist ein [Node.js](https://nodejs.org/en/) Modul über die ## API -{/* eslint-deaktivieren Sie keine unbenutzten vars */} +For ES Modules: + +{/* eslint-disable no-unused-vars */} + +```js +import morgan from 'morgan'; +``` + +For CommonJS: + +{/* 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 +64,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 +72,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 +80,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) { @@ -78,28 +88,30 @@ morgan(function (tokens, req, res) { tokens.method(req, res), tokens.url(req, res), tokens.status(req, res), - tokens.res(req, res, 'content-length'), '-', - tokens['response-time'](https://github.com/expressjs/morgan/blob/HEAD/req, res), 'ms' - ].join(' ') -}) + tokens.res(req, res, 'content-length'), + '-', + tokens['response-time'](req, res), + 'ms', + ].join(' '); +}); ``` #### Optionen 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_. +Schreiben Sie die Logzeile auf Anfrage statt auf Antwort. This means that requests will +be logged even if the server crashes, _but data from the response (like the +response code, content length, etc.) 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,15 +122,42 @@ morgan('combined', { }); ``` -##### streamen +##### stream Ausgabe-Stream zum Schreiben von Logzeilen, standardmäßig `process.stdout`. +If the stream is in object mode (`stream.writableObjectMode` is `true`) and the +format function returns an object, the object is written to the stream as-is, +without a trailing newline. This allows passing structured log entries to +loggers that accept objects: + +{/* eslint-disable no-undef */} + +```js +morgan( + function (tokens, req, res) { + return { + method: tokens.method(req, res), + url: tokens.url(req, res), + status: Number(tokens.status(req, res)), + }; + }, + { + stream: { + writableObjectMode: true, + write: function (entry) { + // entry is the object returned by the format function + }, + }, + } +); +``` + #### Vordefinierte Formate Es werden verschiedene vordefinierte Formate bereitgestellt: -##### kombiniert +##### combined Standard Apache kombinierte Logausgabe. @@ -128,7 +167,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 +177,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 +190,12 @@ für Informationscodes. GET /dev 200 0.224 ms - 2 ``` -##### kurz +Coloring is disabled when the [`NO_COLOR`](https://no-color.org) environment +variable is set to any non-empty value, in which case the output above is +written without any escape sequences. The variable is read once, when `morgan` +is first required. + +##### short Kürzer als Standardwert, auch mit Antwortzeit. @@ -161,7 +205,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 +223,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) { @@ -191,8 +235,8 @@ Wenn `morgan.token()` mit dem gleichen Namen wie ein bestehendes Token aufgerufe Token Definition überschrieben. Die Token-Funktion wird voraussichtlich mit den Argumenten `req` und `res` aufgerufen, die -die HTTP-Anfrage und HTTP-Antwort repräsentieren. Zusätzlich kann das Token weitere Argumente von -akzeptieren, da es das Verhalten anpassen möchte. +die HTTP-Anfrage und HTTP-Antwort repräsentieren. Additionally, the token can accept further arguments of +its choosing to customize behavior. ##### :date[format] @@ -200,11 +244,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. @@ -218,13 +262,13 @@ Die Prozess-ID des Node.js Prozesses zur Bearbeitung der Anfrage. ##### -Der Referrer-Header der Anfrage. Dies wird den Standard-falsch geschriebenen Referer-Header verwenden, falls vorhanden, andernfalls Referrer. +Der Referrer-Header der Anfrage. This will use the standard mis-spelled Referer header if it exists, otherwise Referrer. ##### :remote-addr 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 +282,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 +298,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. @@ -264,9 +308,9 @@ 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`. +Die URL der Anfrage. This will use `req.originalUrl` if it exists, otherwise `req.url`. -##### :user-Agent +##### :user-agent Der Inhalt des User-Agent-Headers der Anfrage. @@ -274,11 +318,11 @@ Der Inhalt des User-Agent-Headers der Anfrage. Kompiliere einen Format-String in eine `format` Funktion für `morgan`. Ein Format-String ist eine Zeichenkette, die eine einzige Protokollzeile repräsentiert und die Token-Syntax verwenden kann. -Token sind Referenzen von `:token-name`. Wenn Tokens Argumente akzeptieren, können sie +Tokens are referenced by `:token-name`. Wenn Tokens Argumente akzeptieren, können sie 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,9 +332,9 @@ 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 +Sample app that will log all requests in the Apache combined format to STDOUT ```js var express = require('express'); @@ -307,7 +351,7 @@ app.get('/', function (req, res) { ### vanilla http Server -Beispiel-App, die alle Anfragen im Apache kombinierten Format in STDOUT protokolliert +Sample app that will log all requests in the Apache combined format to STDOUT ```js var finalhandler = require('finalhandler'); @@ -431,7 +475,7 @@ Beispiel-App, die benutzerdefinierte Token-Formate verwendet. Dies fügt eine ID ```js var express = require('express'); var morgan = require('morgan'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); morgan.token('id', function getId(req) { return req.id; diff --git a/src/content/pages/de/resources/middleware/multer.mdx b/src/content/pages/de/resources/middleware/multer.mdx index ff04f97fbb..e212c878e7 100644 --- a/src/content/pages/de/resources/middleware/multer.mdx +++ b/src/content/pages/de/resources/middleware/multer.mdx @@ -8,8 +8,8 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -18,23 +18,6 @@ oben auf [busboy](https://github.com/mscdex/busboy) geschrieben, um maximale Eff **HINWEIS**: Multer wird keine Form verarbeiten, die nicht multipart ist (`multipart/form-data`). -## Übersetzungen - -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 | - ## Installation @@ -130,23 +113,26 @@ app.post('/stats', upload.single('uploaded_file'), function (req, res) { }); ``` +Complete client-side and server-side examples (browser `FormData` uploads of a +blob and of an image) are in the [`examples/`](https://github.com/expressjs/multer/blob/HEAD/examples/) folder. + ## API ### Dateiinformation Jede Datei enthält folgende Informationen: -| Schlüssel | Beschreibung | Notiz | -| -------------- | ---------------------------------------------- | --------------- | -| Feldname | Feldname im Formular angegeben | | -| `originalname` | Name der Datei auf dem Computer des Benutzers | | -| `codieren` | 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` | -| `path` | Der vollständige Pfad zur hochgeladenen Datei | `DiskStorage` | -| 'buffer' | Ein `Buffer` der gesamten Datei | `MemoryStorage` | +| Schlüssel | Beschreibung | Notiz | +| -------------- | ----------------------------------------------------------------------------------- | --------------- | +| `fieldname` | Feldname im Formular angegeben | | +| `originalname` | Name of the file on the user's computer, or the full path when `preservePath: true` | | +| `encoding` | Kodierungstyp der Datei | | +| `mimetype` | Mime-Typ der Datei | | +| `size` | Größe der Datei in Bytes | | +| `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` | ### `multer(opts)` @@ -159,13 +145,17 @@ 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 | +| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `defCharset` | Default character set to use for text field values that do not declare one. Default: `'utf8'` | +| `defParamCharset` | Standardzeichensatz für Werte von Bauteilheader-Parametern (z.B. Dateiname), die keine erweiterten Parameter sind (welche einen expliziten Zeichensatz enthalten). Standard: `'latin1'` | +| `dest` oder `storage` | Wo die Dateien gespeichert werden sollen | +| `fileFilter` | Funktion, um zu kontrollieren, welche Dateien akzeptiert werden | +| `fileHwm` | `highWaterMark` of each file stream (`file.stream`). Default: busboy's default | +| `highWaterMark` | `highWaterMark` of the multipart parser stream. Default: busboy's default | +| `limits` | Grenzen der hochgeladenen Daten | +| `preservePath` | Keep the full client-supplied path in `file.originalname` instead of just the base name | +| `streamHandler` | Function that feeds the request body to busboy; defaults to `req.pipe(busboy)` | In einer durchschnittlichen Web-App könnte nur `dest` erforderlich sein, und konfiguriert werden, wie in das folgende Beispiel. @@ -174,21 +164,32 @@ das folgende Beispiel. const upload = multer({ dest: 'uploads/' }); ``` +When `preservePath` is enabled, Multer passes the incoming filename through with +any path segments provided by the client. This is exposed as `file.originalname`; +it does not change the destination folder, create directories, or sanitize the +path for you. `file.originalname` is always client-supplied and should be treated +as untrusted; with `preservePath` it additionally contains the path segments the +client sent. Normalize or validate it before using it in a custom `filename` or +storage engine. + Wenn du mehr Kontrolle über deine Uploads haben möchtest, möchtest du die Option `storage` 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. +Files skipped by `fileFilter` do not count towards `maxCount`. Use +`limits.files` to bound how many files are read from a request. + #### `.fields(fields)` Akzeptieren Sie einen Mix von Dateien, angegeben durch `fields`. Ein Objekt mit Arrays von Dateien @@ -206,12 +207,12 @@ Beispiel: #### `.none()` -Nur Textfelder akzeptieren. Wenn eine Datei hochgeladen wurde, wird ein Fehler mit dem Code -"LIMIT_UNEXPECTED_FILE" ausgelöst. +Nur Textfelder akzeptieren. If any file upload is made, error with code +`LIMIT_UNEXPECTED_FILE` will be issued. #### `.any()` -Akzeptiert alle Dateien, die über das Kabel kommen. Ein Array von Dateien wird in +Accepts all files that come over the wire. Ein Array von Dateien wird in `req.files` gespeichert. **WARNUNG:** Stellen Sie sicher, dass Sie immer die Dateien behandeln, die ein Benutzer hochlädt. @@ -219,28 +220,33 @@ 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` Die Festplattenspeicher-Engine gibt Ihnen die volle Kontrolle über die Speicherung von Dateien auf der Festplatte. ```javascript +const crypto = require('crypto'); + const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/tmp/my-uploads'); }, filename: function (req, file, cb) { - const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); - cb(null, file.fieldname + '-' + uniqueSuffix); + crypto.randomBytes(16, function (err, raw) { + if (err) return cb(err); + cb(null, file.fieldname + '-' + raw.toString('hex')); + }); }, }); const upload = multer({ storage: storage }); ``` -Es sind zwei Optionen verfügbar, `destination` und `filename`. Es sind beide --Funktionen, die bestimmen, wo die Datei gespeichert werden soll. +There are three options available: `destination`, `filename` and `flush`. All of +them except `flush` are functions that determine where the file should be +stored. `destination` wird verwendet, um festzustellen, in welchem Ordner die hochgeladenen Dateien gespeichert werden sollen. Dies kann auch als `string` angegeben werden (z.B. `'/tmp/uploads'`). Wenn kein @@ -266,7 +272,15 @@ 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) + +`flush` is an optional boolean. When set to `true`, the file data is flushed to +disk with an `fsync` call before the upload handler runs, which prevents data +loss if the process or the system crashes while the data is still sitting in +the operating system's page cache. It is disabled by default because forcing a +disk flush on every upload has a performance cost. Note that this syncs the +file contents only; if the new directory entry must survive a crash as well, +fsync the destination directory yourself. #### `MemoryStorage` @@ -285,26 +299,42 @@ 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 passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#exports). -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). +`limits` can also be a function that receives the request and returns such an +object. It is called once per request, before parsing starts, so limits can +depend on e.g. the authenticated user: + +```javascript +const upload = multer({ + limits: function (req) { + return { fileSize: req.user.maxUploadSize }; + }, +}); +``` + +Limits apply to the whole request; there is no per-file limit. To restrict +individual files by type or name, use `fileFilter` or a custom storage engine. 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 | -| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Unendlichkeit | +| Schlüssel | Beschreibung | Standard | +| ---------------------- | ---------------------------------------------------------------------------------------------------- | ------------- | +| `fieldNameSize` | Max. Feldnamensgröße | Unendlichkeit | +| `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 | +| `fieldArrayIndexLimit` | Max numeric array index accepted inside a field name (e.g. `a[3]` uses index 3) | 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: @@ -325,6 +355,30 @@ function fileFilter(req, file, cb) { } ``` +### `streamHandler` + +By default Multer reads the request with `req.pipe(busboy)`. Some platforms +consume the request body before your handlers run, so there is nothing left to +pipe. Google Cloud Functions and Firebase Functions, for example, expose the +already-read body as `req.rawBody`. Provide a `streamHandler` to feed busboy +yourself in that case: + +```javascript +const upload = multer({ + storage: multer.memoryStorage(), + streamHandler: function (req, busboy) { + if (req.rawBody) { + busboy.end(req.rawBody); + } else { + req.pipe(busboy); + } + }, +}); +``` + +The function receives the request and the busboy instance and must write the +whole multipart body to busboy and end it. + ## Security Specifying the [limits](#limits) can help protect your site against denial of service (DoS) attacks. The following limits are recommended for most applications: @@ -333,6 +387,7 @@ Specifying the [limits](#limits) can help protect your site against denial of se - `files` -- set to the maximum number of files per request - `fields` -- set to the maximum number of text fields per request - `fieldNestingDepth` -- set to the minimum depth your field names require (e.g. `3` for `a[b][c]`) +- `fieldArrayIndexLimit` -- set to the largest array index your field names require (e.g. `100` for `a[99]`) ## Fehlerbehandlung @@ -340,7 +395,12 @@ 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`). + +Multer errors carry a `code` (e.g. `LIMIT_FILE_SIZE`) and, when the error concerns +a specific field, its name in `field`. Errors about a specific file +(`LIMIT_FILE_SIZE`, `LIMIT_UNEXPECTED_FILE`) also expose the client-supplied file +name in `filename`; treat it as untrusted input, like `file.originalname`. ```javascript const multer = require('multer'); @@ -368,5 +428,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..e5aa07b96c 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,40 +37,40 @@ 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)` +Diese Filterfunktion auf Dateien anwenden. Defaults to `false`. Die `filter` Funktion +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). ##### hidden -Versteckte (Punkte) Dateien anzeigen. Standard ist `false`. +Versteckte (Punkte) Dateien anzeigen. Defaults to `false`. -##### symbole +##### icons -Symbole anzeigen. Standard ist `false`. +Symbole anzeigen. Defaults to `false`. ##### stylesheet 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`. @@ -149,8 +149,8 @@ app.listen(3000); ## Lizenz -[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). Die [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) Icons -werden von/Copyright von [FAMFAMFAM]erstellt (https://web.archive.org/web/20251120154741/http://www.famfamfam.com/). +[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). The [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) icons +are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20230109095739/http://www.famfamfam.com/). [appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index [downloads-url]: https://npmjs.org/package/serve-index 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..482f59b013 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,10 +125,10 @@ 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. +Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`][rfc-cutler-httpbis-partitioned-cookies] +attribute. Wenn Wahrheit, ist das `Partitioned` Attribut gesetzt, andernfalls nicht. Standardmäßig ist das Attribut `Partitioned` nicht gesetzt. **Notiz** Dies ist ein Attribut, das noch nicht vollständig standardisiert wurde und in Zukunft in @@ -138,10 +138,16 @@ 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 +Since 1.19.1, path matching follows [RFC 6265 section 5.1.4][rfc-6265-5.1.4]. This means +the session middleware will only activate when the request path is an exact match or falls +under a segment boundary of the cookie path. For example, a cookie path of `/admin` will +match `/admin` and `/admin/users` but will **not** match `/administrator`. Prior versions +used a simple prefix check that did not enforce segment boundaries. + +##### cookie.priority Legt den `string` als Wert für das [`Priority` `Set-Cookie` Attribut][rfc-west-cookie-priority-00-4.1] fest. @@ -285,7 +291,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 +310,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 +331,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 +349,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 +377,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 +429,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 +440,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 +451,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 +602,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 @@ -1000,8 +1006,9 @@ Verwenden Sie unter Windows den entsprechenden Befehl; [MIT](https://github.com/expressjs/session/blob/HEAD/LICENSE) +[rfc-6265-5.1.4]: https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 [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 1965f2d208..558024dc89 100644 --- a/src/content/pages/es/advanced/best-practice-security.mdx +++ b/src/content/pages/es/advanced/best-practice-security.mdx @@ -48,7 +48,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) { @@ -269,7 +269,7 @@ $ npm audit Si quieres estar más seguro, considera [Snyk](https://snyk.io/). -Snyk ofrece una [herramienta de línea de comandos](https://www.npmjs.com/package/snyk) y una [integración de Github](https://snyk.io/docs/github) que comprueba tu aplicación contra [la base de datos de vulnerabilidad de código abierto de Snyk](https://snyk.io/vuln/) para cualquier vulnerabilidad conocida en tus dependencias. Instalar el CLI de la siguiente manera: +Snyk ofrece una [herramienta de línea de comandos](https://www.npmjs.com/package/snyk) y una [integración de Github](https://docs.snyk.io/discover-snyk/getting-started) que comprueba tu aplicación contra [la base de datos de vulnerabilidad de código abierto de Snyk](https://security.snyk.io/) para cualquier vulnerabilidad conocida en tus dependencias. Instalar el CLI de la siguiente manera: ```bash $ npm install -g snyk @@ -286,7 +286,7 @@ $ snyk test Keep an eye out for [GitHub Advisory Database](https://github.com/advisories?query=ecosystem%3Anpm) or [Snyk](https://security.snyk.io/vuln/npm) advisories that may affect Express or other modules that your app uses. En general, estas bases de datos son excelentes recursos para conocimientos y herramientas sobre la seguridad de Node. -Finalmente, las aplicaciones Express—como cualquier otra aplicación web—pueden ser vulnerables a una variedad de ataques basados en la web. Familiarizarse con [vulnerabilidades web](https://www.owasp.org/www-project-top-ten/) y tomar precauciones para evitarlas. +Finalmente, las aplicaciones Express—como cualquier otra aplicación web—pueden ser vulnerables a una variedad de ataques basados en la web. Familiarizarse con [vulnerabilidades web](https://owasp.org/www-project-top-ten/) y tomar precauciones para evitarlas. ## Consideraciones adicionales @@ -294,8 +294,8 @@ Estas son algunas recomendaciones adicionales de la excelente [Lista de verifica - Siempre filtrar y limpiar la entrada del usuario para proteger contra ataques de cross-site scripting (XSS) e inyección de comandos. - Defienda contra ataques de inyección de SQL usando consultas parametrizadas o sentencias preparadas. -- Utilice la herramienta de código abierto [sqlmap](http://sqlmap.org/) para detectar vulnerabilidades de inyección SQL en su aplicación. +- Utilice la herramienta de código abierto [sqlmap](https://sqlmap.org/) para detectar vulnerabilidades de inyección SQL en su aplicación. - Utilice las herramientas [nmap](https://nmap.org/) y [sslyze](https://github.com/nabla-c0d3/sslyze) para probar la configuración de sus cifrados SSL, llaves, renegociación, así como la validez de su certificado. -- Usa [safe-regex](https://www.npmjs.com/package/safe-regex) para asegurar que tus expresiones regulares no sean susceptibles a los ataques de [denegación de expresión regular de servicio](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). +- Usa [safe-regex](https://www.npmjs.com/package/safe-regex) para asegurar que tus expresiones regulares no sean susceptibles a los ataques de [denegación de expresión regular de servicio](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS). -[helmet]: https://helmetjs.github.io/ +[helmet]: https://helmet.js.org/ 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/guide/migrating-4.mdx b/src/content/pages/es/guide/migrating-4.mdx index 204b7fe6bb..7db18cff01 100644 --- a/src/content/pages/es/guide/migrating-4.mdx +++ b/src/content/pages/es/guide/migrating-4.mdx @@ -43,133 +43,23 @@ que es necesario para ejecutar su aplicación. Simplemente sigue estos pasos: La siguiente tabla muestra Express 3 middleware y sus contrapartes en Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Express 3Express 4
- express.bodyParser - - body-parser + - multer -
- express.compresione - - compresión -
- express.cookieSession - - sesión de galletas -
- express.cookieParser - - parser cookie- -
- express.logger - - morgan -
- express.session - - express-sesión -
- express.favicon - - serve-favicon -
- express.responseTime - - tiempo de respuesta -
- express.errorHandler - - errorhandler -
- express.methodOverride - - sobrescribir método -
- express.timeout - - tiempo de espera de conexión -
- express.vhost - - vhost -
- express.csrf - - csurf -
- express.directory - - serve-index -
- express.static - - serve-static -
+| Express 3 | Express 4 | +| ------------------------ | ------------------------------------------------------------------------------------------------------- | +| `express.bodyParser` | [body-parser](https://github.com/expressjs/body-parser) + [multer](https://github.com/expressjs/multer) | +| `express.compress` | [compression](https://github.com/expressjs/compression) | +| `express.cookieSession` | [cookie-session](https://github.com/expressjs/cookie-session) | +| `express.cookieParser` | [cookie-parser](https://github.com/expressjs/cookie-parser) | +| `express.logger` | [morgan](https://github.com/expressjs/morgan) | +| `express.session` | [express-session](https://github.com/expressjs/session) | +| `express.favicon` | [serve-favicon](https://github.com/expressjs/serve-favicon) | +| `express.responseTime` | [response-time](https://github.com/expressjs/response-time) | +| `express.errorHandler` | [errorhandler](https://github.com/expressjs/errorhandler) | +| `express.methodOverride` | [method-override](https://github.com/expressjs/method-override) | +| `express.timeout` | [connect-timeout](https://github.com/expressjs/timeout) | +| `express.vhost` | [vhost](https://github.com/expressjs/vhost) | +| `express.csrf` | [csurf](https://github.com/expressjs/csurf) | +| `express.directory` | [serve-index](https://github.com/expressjs/serve-index) | +| `express.static` | [serve-static](https://github.com/expressjs/serve-static) | Aquí está la [lista completa](https://github.com/senchalabs/connect#middleware) de Middleware Express 4. @@ -305,78 +195,21 @@ que es específico de la ruta. La siguiente tabla muestra otros cambios pequeños pero importantes en Express 4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ObjetoDescripción
Node.jsExpress 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x.
`http.createServer()` - El módulo `http` ya no es necesario, a menos que necesite trabajar directamente con él - (socket.io/SPDY/HTTPS). La aplicación puede iniciarse usando la función `app.listen()`. -
`app.configure()` - La función `app.configure()` ha sido eliminada. Usa la función `process.env.NODE_ENV` o - `app.get('env')` para detectar el entorno y configurar la aplicación en consecuencia. -
`espacios json` - La propiedad de aplicación `json spaces` está deshabilitada por defecto en Express 4. -
`req.accepted()` - Usa `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, y - `req.acceptsLanguages()`. -
`res.location()`Ya no resuelve las URL relativas.
`req.params`Era un arreglo; ahora un objeto.
`res.locals`Era una función; ahora un objeto.
`res.headerSent`Cambiado a `res.headersSent`.
`app.route`Ahora disponible como `app.mountpath`.
`res.on('encabezado')`Eliminado.
`res.charset`Eliminado.
`res.setHeader('Set-Cookie', val)` - La funcionalidad ahora se limita a establecer el valor básico de la cookie. Usa `res.cookie()` - para añadir funcionalidad . -
+| Object | Descripción | +| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Node.js | Express 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x. | +| `http.createServer()` | The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). La aplicación puede iniciarse usando la función `app.listen()`. | +| `app.configure()` | La función `app.configure()` ha sido eliminada. Usa la función `process.env.NODE_ENV` o `app.get('env')` para detectar el entorno y configurar la aplicación en consecuencia. | +| `json spaces` | La propiedad de aplicación `json spaces` está deshabilitada por defecto en Express 4. | +| `req.accepted()` | Usa `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, y `req.acceptsLanguages()`. | +| `res.location()` | No longer resolves relative URLs. | +| `req.params` | Was an array; now an object. | +| `res.locals` | Was a function; now an object. | +| `res.headerSent` | Changed to `res.headersSent`. | +| `app.route` | Now available as `app.mountpath`. | +| `res.on('header')` | Removed. | +| `res.charset` | Removed. | +| `res.setHeader('Set-Cookie', val)` | La funcionalidad ahora se limita a establecer el valor básico de la cookie. Use `res.cookie()` for added functionality. | ## Ejemplo de migración de aplicación diff --git a/src/content/pages/es/resources/middleware/body-parser.mdx b/src/content/pages/es/resources/middleware/body-parser.mdx index 25169dab4e..17b638e06a 100644 --- a/src/content/pages/es/resources/middleware/body-parser.mdx +++ b/src/content/pages/es/resources/middleware/body-parser.mdx @@ -44,6 +44,10 @@ Este módulo proporciona los siguientes analizadores: - [Analizador de cuerpo de texto](#bodyparsertextoptions) - [Analizador del cuerpo del URL codificado](#bodyparserurlencodedoptions) +All parsers support automatic inflation of `gzip`, `br` (brotli), `deflate` +and `zstd` encodings. `zstd` is available in Node.js `^22.15.0` and +`>=23.8.0`. + Otros analizadores de cuerpo en los que podría estar interesado: - [body](https://www.npmjs.com/package/body#readme) @@ -84,9 +88,8 @@ Los varios errores devueltos por este módulo se describen en la ### bodyParser.json([options]) Devuelve middleware que solo analiza `json` y solo mira las solicitudes donde -la cabecera `Content-Type` coincide con la opción `type`. Este analizador acepta cualquier codificación -Unicode del cuerpo y soporta la inflación automática de codificaciones `gzip`, -`br` (brotli) y `deflate`. +la cabecera `Content-Type` coincide con la opción `type`. This parser accepts any +Unicode encoding of the body. Un nuevo objeto `body` que contiene los datos analizados es poblado en el objeto `request` después del middleware (es decir, `req.body`). @@ -146,9 +149,7 @@ de la solicitud. El análisis puede ser abortado lanzando un error. ### bodyParser.raw([options]) Devuelve middleware que analiza todos los cuerpos como un `Buffer` y solo mira solicitudes -donde la cabecera `Content-Type` coincide con la opción `type`. Este analizador -soporta la inflación automática de codificaciones `gzip`, `br` (brotli) y `deflate` -. +donde la cabecera `Content-Type` coincide con la opción `type`. Un nuevo objeto `body` que contiene los datos analizados es poblado en el objeto `request` después del middleware (es decir, `req.body`). Este será un objeto de `Buffer` @@ -194,23 +195,21 @@ de la solicitud. El análisis puede ser abortado lanzando un error. ### bodyParser.text([options]) Devuelve middleware que analiza todos los cuerpos como una cadena y solo mira peticiones -donde la cabecera `Content-Type` coincide con la opción `type`. Este analizador -soporta la inflación automática de codificaciones `gzip`, `br` (brotli) y `deflate` -. +donde la cabecera `Content-Type` coincide con la opción `type`. -Una nueva cadena `body` que contiene los datos analizados es poblada en el objeto `request` -después del middleware (es decir, `req.body`). Esta será una cadena del cuerpo -. +A new `body` string containing the parsed data is populated on the `request` +object after the middleware (i.e. `req.body`). This will be a string of the +body. #### Opciones -La función `text` toma un objeto opcional `options` que puede contener cualquiera de -las siguientes claves: +The `text` function takes an optional `options` object that may contain any of +the following keys: ##### por defecto Charset -Especifica el conjunto de caracteres predeterminado para el contenido del texto si el conjunto de caracteres no es -especificado en la cabecera `Content-Type` de la solicitud. Por defecto es `utf-8`. +Specify the default character set for the text content if the charset is not +specified in the `Content-Type` header of the request. Por defecto es `utf-8`. ##### inflado @@ -233,9 +232,9 @@ parse. Esta opción puede ser una cadena, array de cadenas, o una función. If n a function, `type` option is passed directly to the [type-is](https://www.npmjs.com/package/type-is#readme) library and this can be an extension name (like `txt`), a mime type (like `text/plain`), or a mime -type with a wildcard (like `*/*` or `text/*`). Si una función, la opción `type` -se llama como `fn(req)` y la solicitud se analiza si devuelve un valor verdadero -. Por defecto es `text/plain`. +type with a wildcard (like `*/*` or `text/*`). If a function, the `type` +option is called as `fn(req)` and the request is parsed if it returns a +truthy value. Defaults to `text/plain`. ##### verificar @@ -245,10 +244,9 @@ de la solicitud. El análisis puede ser abortado lanzando un error. ### bodyParser.urlencoded([options]) -Devuelve middleware que solo analiza cuerpos de `urlencoded` y solo mira solicitudes de -donde la cabecera `Content-Type` coincide con la opción `type`. Este analizador -acepta solo codificaciones UTF-8 e ISO-8859-1 del cuerpo y soporta la inflación automática -de codificaciones `gzip`, `br` (brotli) y `deflate`. +Returns middleware that only parses `urlencoded` bodies and only looks at +requests where the `Content-Type` header matches the `type` option. This +parser accepts only UTF-8 and ISO-8859-1 encodings of the body. Un nuevo objeto `body` que contiene los datos analizados es poblado en el objeto `request` después del middleware (es decir, `req.body`). This object will contain @@ -257,17 +255,17 @@ key-value pairs, where the value can be a string or array (when `extended` is #### Opciones -La función `urlencoded` toma un objeto opcional `options` que puede contener -cualquiera de las siguientes claves: +The `urlencoded` function takes an optional `options` object that may contain +any of the following keys: -##### extendido +##### extended -La sintaxis "extendida" permite que objetos y arreglos enriquecidos sean codificados en el formato codificado en URL -, permitiendo una experiencia similar a JSON con codificación URL. Para obtener -más información, por favor ver la librería qs -. +The "extended" syntax allows for rich objects and arrays to be encoded into the +URL-encoded format, allowing for a JSON-like experience with URL-encoded. For +more information, please see the qs +library. -Por defecto es `false`. +Defaults to `false`. ##### inflado @@ -283,11 +281,11 @@ a `'100kb'`. > Se recomienda no configurar un límite muy alto y utilizar el valor por defecto siempre que sea posible. Permitir cargas mayores aumenta el uso de memoria debido a los recursos necesarios para decodificar y transformar, y también puede llevar a tiempos de respuesta más largos a medida que se procesan más datos. Por “muy alto”, nos referimos a valores por encima del valor predeterminado, por ejemplo las cargas útiles de 5 MB o más ya pueden empezar a introducir estos riesgos. Con los límites por defecto, estos problemas no se producen. -##### parámetro límite +##### parameterLimit -La opción `parameterLimit` controla el número máximo de parámetros que -están permitidos en los datos codificados en la URL. Si una solicitud contiene más parámetros -que este valor, se devolverá un 413 al cliente. Por defecto es `1000`. +The `parameterLimit` option controls the maximum number of parameters that +are allowed in the URL-encoded data. If a request contains more parameters +than this value, a 413 will be returned to the client. Defaults to `1000`. ##### tipo @@ -297,9 +295,9 @@ a function, `type` option is passed directly to the [type-is](https://www.npmjs.com/package/type-is#readme) library and this can be an extension name (like `urlencoded`), a mime type (like `application/x-www-form-urlencoded`), or a mime type with a wildcard (like -`*/x-www-form-urlencoded`). Si una función, la opción `type` se llama -`fn(req)` y la solicitud se analiza si devuelve un valor verdadero. Por defecto -a `application/x-www-form-urlencoded`. +`*/x-www-form-urlencoded`). If a function, the `type` option is called as +`fn(req)` and the request is parsed if it returns a truthy value. Defaults +to `application/x-www-form-urlencoded`. ##### verificar @@ -309,131 +307,131 @@ de la solicitud. El análisis puede ser abortado lanzando un error. ##### por defecto Charset -El conjunto de caracteres por defecto a analizar, si no se especifica en el tipo de contenido. Debe ser -ya sea `utf-8` o `iso-8859-1`. Por defecto es `utf-8`. +The default charset to parse as, if not specified in content-type. Must be +either `utf-8` or `iso-8859-1`. Por defecto es `utf-8`. ##### charsetSentinel -Si dejar que el valor del parámetro `utf8` tenga precedencia como selector -. Requiere que el formulario contenga un parámetro llamado `utf8` con un valor -de `mañ`. Por defecto es `false`. +Whether to let the value of the `utf8` parameter take precedence as the charset +selector. It requires the form to contain a parameter named `utf8` with a value +of `✓`. Defaults to `false`. -##### interpretar entidades numéricas +##### interpretNumericEntities -Si decodificar entidades numéricas como `☺` al analizar un formulario iso-8859-1 -. Por defecto es `false`. +Whether to decode numeric entities such as `☺` when parsing an iso-8859-1 +form. Defaults to `false`. -##### profundidad +##### depth -La opción `depth` se utiliza para configurar la profundidad máxima de la librería `qs` cuando `extendido` es `true`. Esto le permite limitar la cantidad de claves que se analizan y pueden ser útiles para prevenir ciertos tipos de abuso. Por defecto es `32`. Se recomienda mantener este valor lo más bajo posible. +The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible. -## Errores +## Errors -Los middlewares proporcionados por este módulo crean errores usando el módulo -[`http-errors`](https://www.npmjs.com/package/http-errors). Los errores -normalmente tendrán una propiedad `status`/`statusCode` que contiene el código de respuesta -sugerido, una propiedad `expose` para determinar si la propiedad `message` -debe mostrarse al cliente, una propiedad `type` para determinar el tipo de error -sin coincidir con el `message`, y una propiedad `body` que contiene -el cuerpo leído, si está disponible. +The middlewares provided by this module create errors using the +[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors +will typically have a `status`/`statusCode` property that contains the suggested +HTTP response code, an `expose` property to determine if the `message` property +should be displayed to the client, a `type` property to determine the type of +error without matching against the `message`, and a `body` property containing +the read body, if available. -Los siguientes son los errores comunes creados, aunque cualquier error puede pasar por -por varias razones. +The following are the common errors created, though any error can come through +for various reasons. -### codificación de contenido no soportada +### content encoding unsupported -Este error ocurrirá cuando la solicitud tuviera una cabecera `Content-Encoding` que -contenía una codificación pero la opción "inflación" se estableció en `false`. La propiedad -`status` se establece en `415`, la propiedad `type` se establece en -`'encoding. nsupported'`, y la propiedad `charset` se establecerá en la codificación -que no es compatible. +This error will occur when the request had a `Content-Encoding` header that +contained an encoding but the "inflation" option was set to `false`. The +`status` property is set to `415`, the `type` property is set to +`'encoding.unsupported'`, and the `charset` property will be set to the +encoding that is unsupported. -### análisis de entidad fallido +### entity parse failed This error will occur when the request contained an entity that could not be -parsed by the middleware. La propiedad `status` se establece en `400`, la propiedad `type` -se establece en `'entity.parse. ailed'`, y la propiedad `body` se establece en -el valor de la entidad que falló en el análisis. +parsed by the middleware. The `status` property is set to `400`, the `type` +property is set to `'entity.parse.failed'`, and the `body` property is set to +the entity value that failed parsing. -### falló la verificación de la entidad +### entity verify failed This error will occur when the request contained an entity that could not be -failed verification by the defined `verify` option. La propiedad `status` es -establecido a `403`, la propiedad `type` se establece en `'entity.verify. ailed'`, y la propiedad -`body` se establece en el valor de la entidad que falló la verificación. +verified by the defined `verify` option. The `status` property is +set to `403`, the `type` property is set to `'entity.verify.failed'`, and the +`body` property is set to the entity value that failed verification. -### solicitud abortada +### request aborted -Este error se producirá cuando el cliente aborte la solicitud antes de leer -el cuerpo ha terminado. La propiedad `received` se establecerá al número de -bytes recibidos antes de que la solicitud fuera abortada y la propiedad `expected` sea -establecido al número de bytes esperados. La propiedad `status` se establece en `400` -y la propiedad `type` se establece en `'request.aborted'`. +This error will occur when the request is aborted by the client before reading +the body has finished. The `received` property will be set to the number of +bytes received before the request was aborted and the `expected` property is +set to the number of expected bytes. The `status` property is set to `400` +and `type` property is set to `'request.aborted'`. -### entidad de solicitud demasiado grande +### request entity too large -Este error ocurrirá cuando el tamaño del cuerpo de solicitud sea mayor que la opción "límite" -. La propiedad `limit` se establecerá al límite de bytes y la propiedad `length` -se establecerá a la longitud del cuerpo de solicitud. La propiedad `status` es -establece a `413` y la propiedad `type` se establece a `'entity.too.large'`. +This error will occur when the request body's size is larger than the "limit" +option. The `limit` property will be set to the byte limit and the `length` +property will be set to the request body's length. The `status` property is +set to `413` and the `type` property is set to `'entity.too.large'`. -### el tamaño de la solicitud no coincide con la longitud del contenido +### request size did not match content length -Este error ocurrirá cuando la longitud de la solicitud no coincida con la longitud de -la cabecera `Content-Length`. Esto normalmente ocurre cuando la solicitud está mal formada, -normalmente cuando la cabecera `Content-Length` fue calculada basado en los caracteres -en lugar de bytes. La propiedad `status` se establece en `400` y la propiedad `type` -se establece en `'request.size.invalid'`. +This error will occur when the request's length did not match the length from +the `Content-Length` header. This typically occurs when the request is malformed, +typically when the `Content-Length` header was calculated based on characters +instead of bytes. The `status` property is set to `400` and the `type` property +is set to `'request.size.invalid'`. -### no debe establecerse la codificación de stream +### stream encoding should not be set -Este error ocurrirá cuando algo llamado el método `req.setEncoding` previo -a este middleware. Este módulo opera directamente sólo en bytes y no puede llamar -a `req.setEncoding` al usar este módulo. La propiedad `status` está establecida en -`500` y la propiedad `type` se establece en `'stream.encoding.set'`. +This error will occur when something called the `req.setEncoding` method prior +to this middleware. This module operates directly on bytes only and you cannot +call `req.setEncoding` when using this module. The `status` property is set to +`500` and the `type` property is set to `'stream.encoding.set'`. -### stream no es legible +### stream is not readable -Este error ocurrirá cuando la solicitud ya no sea legible cuando este middleware -intente leerla. Normalmente significa algo que no sea un middleware de -este módulo lee el cuerpo de la solicitud y el middleware también fue configurado para -leer la misma solicitud. La propiedad `status` se establece en `500` y la propiedad `type` -se establece en `'stream.not.readable'`. +This error will occur when the request is no longer readable when this middleware +attempts to read it. This typically means something other than a middleware from +this module read the request body already and the middleware was also configured to +read the same request. The `status` property is set to `500` and the `type` +property is set to `'stream.not.readable'`. -### demasiados parámetros +### too many parameters -Este error ocurrirá cuando el contenido de la solicitud excede el `parameterLimit` configurado -para el analizador `urlencoded`. La propiedad `status` está establecida en -`413` y la propiedad `type` se establece en `'parameters.too.many'`. +This error will occur when the content of the request exceeds the configured +`parameterLimit` for the `urlencoded` parser. The `status` property is set to +`413` and the `type` property is set to `'parameters.too.many'`. -### conjunto de caracteres no soportado "BOGUS" +### unsupported charset "BOGUS" -Este error ocurrirá cuando la solicitud tenga un parámetro de conjunto de caracteres en la cabecera -`Content-Type`, pero el módulo `iconv-lite` no lo soporta O el analizador -no lo soporta. El conjunto de caracteres está contenido en el mensaje así como en -como en la propiedad `charset`. La propiedad `status` se establece en `415`, la propiedad -`type` se establece en `'charset. nsupported'`, y la propiedad `charset` -está establecida en el conjunto de caracteres que no es compatible. +This error will occur when the request had a charset parameter in the +`Content-Type` header, but the `iconv-lite` module does not support it OR the +parser does not support it. The charset is contained in the message as well +as in the `charset` property. The `status` property is set to `415`, the +`type` property is set to `'charset.unsupported'`, and the `charset` property +is set to the charset that is unsupported. -### codificación de contenido no soportada "bogus" +### unsupported content encoding "bogus" -Este error ocurrirá cuando la solicitud tuviera una cabecera `Content-Encoding` que -contenía una codificación no soportada. La codificación está contenida en el mensaje -así como en la propiedad `encoding`. La propiedad `status` está establecida a `415`, -la propiedad `type` se establece en `'encoding. nsupported'`, y la propiedad `encoding` -está establecida en la codificación que no es compatible. +This error will occur when the request had a `Content-Encoding` header that +contained an unsupported encoding. The encoding is contained in the message +as well as in the `encoding` property. The `status` property is set to `415`, +the `type` property is set to `'encoding.unsupported'`, and the `encoding` +property is set to the encoding that is unsupported. -### La entrada excedió la profundidad +### The input exceeded the depth -Este error ocurre cuando se usa `bodyParser.urlencoded` con la propiedad `extended` establecida a `true` y la entrada excede la opción `depth` configurada. La propiedad `status` está establecida a `400`. Se recomienda revisar la opción `depth` y evaluar si requiere un valor mayor. Cuando la opción `depth` se establece en `32` (valor por defecto), el error no se arrojará. +This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown. ## Ejemplos -### Exprimir/Conectar genéricos de nivel superior +### Express/Connect top-level generic -Este ejemplo demuestra agregar un analizador de JSON genérico y un analizador codificado en URL como un middleware -de nivel superior, el cual analizará los cuerpos de todas las solicitudes entrantes. -Esta es la configuración más sencilla. +This example demonstrates adding a generic JSON and URL-encoded parser as a +top-level middleware, which will parse the bodies of all incoming requests. +This is the simplest setup. ```js const express = require('express'); @@ -454,10 +452,10 @@ app.use(function (req, res) { }); ``` -### Ruta Express específica +### Express route-specific -Este ejemplo demuestra agregar analizadores de cuerpo específicamente a las rutas que -los necesita. En general, esta es la forma más recomendada de usar el analizador del cuerpo con +This example demonstrates adding body parsers specifically to the routes that +need them. In general, this is the most recommended way to use body-parser with Express. ```js @@ -485,10 +483,10 @@ app.post('/api/users', jsonParser, function (req, res) { }); ``` -### Cambiar el tipo aceptado para los analizadores +### Change accepted type for parsers -Todos los analizadores aceptan una opción `type` que te permite cambiar el -`Content-Type` que el middleware analizará. +All the parsers accept a `type` option which allows you to change the +`Content-Type` that the middleware will parse. ```js const express = require('express'); @@ -511,5 +509,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 -[insignia osf-scorecard-scorecard-]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge -[visualizador-escorecard-ossf]: 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/es/resources/middleware/compression.mdx b/src/content/pages/es/resources/middleware/compression.mdx index 063b0dba84..12a6b347b3 100644 --- a/src/content/pages/es/resources/middleware/compression.mdx +++ b/src/content/pages/es/resources/middleware/compression.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -21,13 +21,13 @@ Las siguientes codificaciones de compresión están soportadas: - gzip - br (brotli) -**Nota** Brotli sólo es compatible desde las versiones de Node.js v11.7.0 y v10.16.0. +**Note** Brotli is available in all currently supported Node.js LTS versions (v18+). ## Instalar Este es un módulo [Node.js](https://nodejs.org/en/) disponible a través del [npm registry](https://www.npmjs.com/). La instalación se realiza usando el comando -[`npm install`](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): +[`npm install`](https://docs.npmjs.com/downloading-and-installing-packages-locally): @@ -304,7 +304,7 @@ El proyecto Express.js acoge con satisfacción todas las contribuciones construc desde código para correcciones de errores y mejoras, hasta adiciones y correcciones a la documentación, ¡pruebas adicionales, probando solicitudes y problemas entrantes, y más! -Vea la [Guía de contribución] (https://github.com/expressjs/express/blob/master/Contributing.md) para más detalles técnicos sobre contribuir. +See the [Contributing Guide](https://github.com/expressjs/.github/blob/HEAD/CONTRIBUTING.md) for more technical details on contributing. ## Licencia @@ -312,6 +312,6 @@ Vea la [Guía de contribución] (https://github.com/expressjs/express/blob/maste [npm-url]: https://npmjs.org/package/compression [descarga-url]: https://npmcharts.com/compare/compression?minimal=true -[insignia osf-scorecard-scorecard-]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge -[visualizador-escorecard-ossf]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression +[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 [url de financiación]: https://opencollective.com/express diff --git a/src/content/pages/es/resources/middleware/morgan.mdx b/src/content/pages/es/resources/middleware/morgan.mdx index 2e7b04ac67..321dbe2014 100644 --- a/src/content/pages/es/resources/middleware/morgan.mdx +++ b/src/content/pages/es/resources/middleware/morgan.mdx @@ -8,14 +8,14 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; Middleware del registrador de peticiones HTTP para node.js -> Nombrado después de [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), una serie que no debes ver hasta que termines. +> Named after [Dexter](https://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. ## Instalación @@ -35,6 +35,16 @@ Este es un módulo [Node.js](https://nodejs.org/en/) disponible a través del ## API +For ES Modules: + +{/* eslint-disable no-unused-vars */} + +```js +import morgan from 'morgan'; +``` + +For CommonJS: + {/* eslint-disable no-unused-vars */} ```js @@ -78,10 +88,12 @@ morgan(function (tokens, req, res) { tokens.method(req, res), tokens.url(req, res), tokens.status(req, res), - tokens.res(req, res, 'content-length'), '-', - tokens['response-time'](https://github.com/expressjs/morgan/blob/HEAD/req, res), 'ms' - ].join(' ') -}) + tokens.res(req, res, 'content-length'), + '-', + tokens['response-time'](req, res), + 'ms', + ].join(' '); +}); ``` #### Opciones @@ -90,9 +102,9 @@ Morgan acepta estas propiedades en el objeto de opciones. ##### inmediato -Escriba la línea de registro a petición en lugar de respuesta. Esto significa que una solicitud se registrará -incluso si el servidor falla, _but datos de la respuesta (como el código de respuesta -, longitud de contenido, etc.) no se puede registrar_. +Escriba la línea de registro a petición en lugar de respuesta. This means that requests will +be logged even if the server crashes, _but data from the response (like the +response code, content length, etc.) no se puede registrar_. ##### saltar @@ -114,6 +126,33 @@ morgan('combined', { stream de salida para escribir líneas de registro, por defecto en `process.stdout`. +If the stream is in object mode (`stream.writableObjectMode` is `true`) and the +format function returns an object, the object is written to the stream as-is, +without a trailing newline. This allows passing structured log entries to +loggers that accept objects: + +{/* eslint-disable no-undef */} + +```js +morgan( + function (tokens, req, res) { + return { + method: tokens.method(req, res), + url: tokens.url(req, res), + status: Number(tokens.status(req, res)), + }; + }, + { + stream: { + writableObjectMode: true, + write: function (entry) { + // entry is the object returned by the format function + }, + }, + } +); +``` + #### Formatos predefinidos Hay varios formatos predefinidos proporcionados: @@ -151,6 +190,11 @@ no coloreado para códigos de información. GET /dev 200 0.224 ms - 2 ``` +Coloring is disabled when the [`NO_COLOR`](https://no-color.org) environment +variable is set to any non-empty value, in which case the output above is +written without any escape sequences. The variable is read once, when `morgan` +is first required. + ##### corto Más corto que el valor predeterminado, incluyendo también el tiempo de respuesta. @@ -191,8 +235,8 @@ Calling `morgan.token()` using the same name as an existing token will overwrite token definition. Se espera que la función de token sea llamada con los argumentos `req` y `res`, representando -la solicitud HTTP y la respuesta HTTP. Además, el token puede aceptar otros argumentos de -está eligiendo personalizar el comportamiento. +la solicitud HTTP y la respuesta HTTP. Additionally, the token can accept further arguments of +its choosing to customize behavior. ##### :date[format] @@ -218,7 +262,7 @@ El ID de proceso del proceso Node.js que maneja la solicitud. ##### -La cabecera del Referrer de la solicitud. Esto usará la cabecera de referencia mal escrita estándar si existe, de lo contrario Referrer. +La cabecera del Referrer de la solicitud. This will use the standard mis-spelled Referer header if it exists, otherwise Referrer. ##### :remote-addr @@ -264,7 +308,7 @@ incluir en el número, por defecto a `3`, que proporciona precisión microsegund ##### -La URL de la solicitud. Esto usará `req.originalUrl` si existe, de lo contrario `req.url`. +La URL de la solicitud. This will use `req.originalUrl` if it exists, otherwise `req.url`. ##### :user-agent @@ -274,13 +318,13 @@ El contenido del encabezado User-Agent de la solicitud. Compila una cadena de formato en una función `format` para usarla por `morgan`. Una cadena de formato es una cadena que representa una única línea de registro y puede utilizar sintaxis de token. -Las fichas son referencias de `:token-name`. Si los tokens aceptan argumentos, pueden pasar +Tokens are referenced by `:token-name`. Si los tokens aceptan argumentos, pueden pasar usando `[]`, por ejemplo: `:token-name[pretty]` pasaría la cadena `'srcty'` como un argumento al token `token-name`. -La función devolvió de `morgan. ompile` toma tres argumentos `tokens`, `req` y -`res`, donde `tokens` es objeto con todos los tokens definidos, `req` es la petición HTTP y -`res` es la respuesta HTTP. La función devolverá una cadena que será la línea de registro, +The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and +`res`, where `tokens` is an object with all defined tokens, `req` is the HTTP request and +`res` is the HTTP response. La función devolverá una cadena que será la línea de registro, o `undefined` / `null` para omitir el registro. Normally formats are defined using `morgan.format(name, format)`, but for certain @@ -290,7 +334,7 @@ advanced uses, this compile function is directly available. ### expresar/conectar -Aplicación de ejemplo que registrará todas las peticiones en el formato combinado de Apache en STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var express = require('express'); @@ -307,7 +351,7 @@ app.get('/', function (req, res) { ### servidor http vainilla -Aplicación de ejemplo que registrará todas las peticiones en el formato combinado de Apache en STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var finalhandler = require('finalhandler'); @@ -431,7 +475,7 @@ Aplicación de ejemplo que utilizará formatos de token personalizados. Esto añ ```js var express = require('express'); var morgan = require('morgan'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); morgan.token('id', function getId(req) { return req.id; diff --git a/src/content/pages/es/resources/middleware/multer.mdx b/src/content/pages/es/resources/middleware/multer.mdx index cd0125fdb7..4f8b4fe80b 100644 --- a/src/content/pages/es/resources/middleware/multer.mdx +++ b/src/content/pages/es/resources/middleware/multer.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -18,23 +18,6 @@ encima de [busboy](https://github.com/mscdex/busboy) para máxima eficiencia. **NOTA**: Multer no procesará ninguna forma que no sea multiparte (`multipart/form-data`). -## Traducciones - -Este README también está disponible en otros idiomas: - -| | | -| ------------------------------------------------------------------------------ | -------------- | -| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Árabe | -| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chino | -| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | Francés | -| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Coreano | -| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portugués (BR) | -| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Ruso | -| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Español | -| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek | -| [Ver Nombre](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) | Turco | - ## Instalación @@ -130,23 +113,26 @@ app.post('/stats', upload.single('uploaded_file'), function (req, res) { }); ``` +Complete client-side and server-side examples (browser `FormData` uploads of a +blob and of an image) are in the [`examples/`](https://github.com/expressjs/multer/blob/HEAD/examples/) folder. + ## API ### Información del archivo Cada archivo contiene la siguiente información: -| Clave | Descripción | Nota | -| ------------------- | ---------------------------------------------- | ---------------- | -| `nombrecampo` | Nombre de campo especificado en el formulario | | -| `nombre original` | Nombre del archivo en el equipo del usuario | | -| `codificación` | Tipo de codificación del archivo | | -| `mimetype` | Tipo Mime del archivo | | -| `size` | Tamaño del archivo en bytes | | -| `destino` | La carpeta en la que se ha guardado el archivo | `DiskStorage` | -| `nombre de archivo` | El nombre del archivo dentro del `destino` | `DiskStorage` | -| `ruta` | La ruta completa al archivo subido | `DiskStorage` | -| `búfer` | Un `Buffer` de todo el archivo | `MemoriaStorage` | +| Clave | Descripción | Nota | +| ------------------- | ----------------------------------------------------------------------------------- | ---------------- | +| `nombrecampo` | Nombre de campo especificado en el formulario | | +| `nombre original` | Name of the file on the user's computer, or the full path when `preservePath: true` | | +| `codificación` | Tipo de codificación del archivo | | +| `mimetype` | Tipo Mime del archivo | | +| `size` | Tamaño del archivo en bytes | | +| `destino` | La carpeta en la que se ha guardado el archivo | `DiskStorage` | +| `nombre de archivo` | El nombre del archivo dentro del `destino` | `DiskStorage` | +| `ruta` | La ruta completa al archivo subido | `DiskStorage` | +| `búfer` | Un `Buffer` de todo el archivo | `MemoriaStorage` | ### `multer(opts)` @@ -161,11 +147,15 @@ Las siguientes son las opciones que se pueden pasar a Multer. | Clave | Descripción | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `defCharset` | Default character set to use for text field values that do not declare one. Default: `'utf8'` | +| `defParamCharset` | Juego de caracteres por defecto para los valores de los parámetros de la cabecera de partes (por ejemplo, nombre de archivo) que no son parámetros extendidos (que contienen un conjunto de caracteres explícito). Predeterminado: `'latin1'` | | `dest` o `storage` | Dónde guardar los archivos | | `fileFilter` | Función para controlar qué archivos son aceptados | +| `fileHwm` | `highWaterMark` of each file stream (`file.stream`). Default: busboy's default | +| `highWaterMark` | `highWaterMark` of the multipart parser stream. Default: busboy's default | | `limites` | Límites de los datos subidos | -| `preservePath` | Mantener la ruta completa de los archivos en lugar del nombre base | -| `defParamCharset` | Juego de caracteres por defecto para los valores de los parámetros de la cabecera de partes (por ejemplo, nombre de archivo) que no son parámetros extendidos (que contienen un conjunto de caracteres explícito). Predeterminado: `'latin1'` | +| `preservePath` | Keep the full client-supplied path in `file.originalname` instead of just the base name | +| `streamHandler` | Function that feeds the request body to busboy; defaults to `req.pipe(busboy)` | En una aplicación web promedio, sólo `dest` puede ser requerido, y configurado como se muestra en el siguiente ejemplo. @@ -174,6 +164,14 @@ el siguiente ejemplo. const upload = multer({ dest: 'uploads/' }); ``` +When `preservePath` is enabled, Multer passes the incoming filename through with +any path segments provided by the client. This is exposed as `file.originalname`; +it does not change the destination folder, create directories, or sanitize the +path for you. `file.originalname` is always client-supplied and should be treated +as untrusted; with `preservePath` it additionally contains the path segments the +client sent. Normalize or validate it before using it in a custom `filename` or +storage engine. + Si quieres más control sobre tus subidas, querrás usar la opción `storage` en lugar de `dest`. Múltiples naves con motores de almacenamiento `DiskStorage` y `MemoryStorage`; Hay más motores disponibles de terceros. @@ -189,6 +187,9 @@ Acepta una matriz de archivos, todo con el nombre `fieldname`. Opcionalmente un más de archivos `maxCount` son subidos. El array de archivos se almacenará en `req.files`. +Files skipped by `fileFilter` do not count towards `maxCount`. Use +`limits.files` to bound how many files are read from a request. + #### `.fields(campos)` Acepta una mezcla de archivos, especificada por `fields`. Un objeto con arrays de archivos @@ -206,12 +207,12 @@ Ejemplo: #### `.None ()` -Aceptar sólo campos de texto. Si se realiza cualquier carga de archivos, se emitirá un error con el código -"LIMIT_UNEXPECTED_FILE". +Aceptar sólo campos de texto. If any file upload is made, error with code +`LIMIT_UNEXPECTED_FILE` will be issued. #### `.any()` -Acepta todos los archivos que pasan por el cable. Un array de archivos se almacenará en +Accepts all files that come over the wire. Un array de archivos se almacenará en `req.files`. **ADVERTENCIA:** Asegúrate de que siempre gestionas los archivos que sube un usuario. @@ -226,21 +227,26 @@ donde esté manejando los archivos cargados. El motor de almacenamiento de disco le da un control total sobre el almacenamiento de archivos en disco. ```javascript +const crypto = require('crypto'); + const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/tmp/my-uploads'); }, filename: function (req, file, cb) { - const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); - cb(null, file.fieldname + '-' + uniqueSuffix); + crypto.randomBytes(16, function (err, raw) { + if (err) return cb(err); + cb(null, file.fieldname + '-' + raw.toString('hex')); + }); }, }); const upload = multer({ storage: storage }); ``` -Hay dos opciones disponibles, `destination` y `filename`. Son ambas funciones -que determinan dónde debe almacenarse el archivo. +There are three options available: `destination`, `filename` and `flush`. All of +them except `flush` are functions that determine where the file should be +stored. `destination` se utiliza para determinar dentro de qué carpeta deben guardarse los archivos subidos . Esto también se puede dar como una `cadena` (por ejemplo, `'/tmp/uploads'`). Si no se da @@ -268,6 +274,14 @@ Para entender la convención de llamada utilizada en el callback (necesidad de p null como primer parámetro), consulte [Nodo. s gestión de errores](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors) +`flush` is an optional boolean. When set to `true`, the file data is flushed to +disk with an `fsync` call before the upload handler runs, which prevents data +loss if the process or the system crashes while the data is still sitting in +the operating system's page cache. It is disabled by default because forcing a +disk flush on every upload has a performance cost. Note that this syncs the +file contents only; if the new directory entry must survive a crash as well, +fsync the destination directory yourself. + #### `MemoriaStorage` El motor de almacenamiento de memoria almacena los archivos en memoria como objetos `Buffer`. no tiene ninguna opción. @@ -286,20 +300,36 @@ de almacenamiento de memoria. ### `limites` -Un objeto que especifica los límites de tamaño de las siguientes propiedades opcionales. Multer pasa este objeto directamente a busboy, y los detalles de las propiedades se pueden encontrar en la [página de busbo](https://github.com/mscdex/busboy#busboy-methods). +Un objeto que especifica los límites de tamaño de las siguientes propiedades opcionales. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#exports). + +`limits` can also be a function that receives the request and returns such an +object. It is called once per request, before parsing starts, so limits can +depend on e.g. the authenticated user: + +```javascript +const upload = multer({ + limits: function (req) { + return { fileSize: req.user.maxUploadSize }; + }, +}); +``` + +Limits apply to the whole request; there is no per-file limit. To restrict +individual files by type or name, use `fileFilter` or a custom storage engine. Los siguientes valores enteros están disponibles: -| Clave | Descripción | Por defecto | -| ------------------- | --------------------------------------------------------------------------------------------- | ----------- | -| `campoNombre` | Tamaño máximo del nombre del campo | 100 bytes | -| `fieldSize` | Tamaño máximo del campo (en bytes) | 1 MB | -| `campos` | Número máximo de campos que no son archivos | Infinidad | -| `fileSize` | Para formularios multiparte, el tamaño máximo de archivo (en bytes) | Infinidad | -| `archivos` | Para formularios de varias partes, el número máximo de campos de archivo | Infinidad | -| `partes` | Para formularios de varias partes, el número máximo de partes (campos + archivos) | Infinidad | -| `pares de cabecera` | Para formularios de varias partes, el número máximo de pares de cabecera=>valor para analizar | 2000 | -| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinidad | +| Clave | Descripción | Por defecto | +| ---------------------- | --------------------------------------------------------------------------------------------- | ----------- | +| `campoNombre` | Tamaño máximo del nombre del campo | Infinidad | +| `fieldSize` | Tamaño máximo del campo (en bytes) | 1 MB | +| `campos` | Número máximo de campos que no son archivos | Infinidad | +| `fileSize` | Para formularios multiparte, el tamaño máximo de archivo (en bytes) | Infinidad | +| `archivos` | Para formularios de varias partes, el número máximo de campos de archivo | Infinidad | +| `partes` | Para formularios de varias partes, el número máximo de partes (campos + archivos) | Infinidad | +| `pares de cabecera` | Para formularios de varias partes, el número máximo de pares de cabecera=>valor para analizar | 2000 | +| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinidad | +| `fieldArrayIndexLimit` | Max numeric array index accepted inside a field name (e.g. `a[3]` uses index 3) | Infinidad | Especificar los límites puede ayudar a proteger su sitio contra ataques de denegación de servicio (DoS). @@ -324,6 +354,30 @@ function fileFilter(req, file, cb) { } ``` +### `streamHandler` + +By default Multer reads the request with `req.pipe(busboy)`. Some platforms +consume the request body before your handlers run, so there is nothing left to +pipe. Google Cloud Functions and Firebase Functions, for example, expose the +already-read body as `req.rawBody`. Provide a `streamHandler` to feed busboy +yourself in that case: + +```javascript +const upload = multer({ + storage: multer.memoryStorage(), + streamHandler: function (req, busboy) { + if (req.rawBody) { + busboy.end(req.rawBody); + } else { + req.pipe(busboy); + } + }, +}); +``` + +The function receives the request and the busboy instance and must write the +whole multipart body to busboy and end it. + ## Security Specifying the [limits](#limits) can help protect your site against denial of service (DoS) attacks. The following limits are recommended for most applications: @@ -332,15 +386,21 @@ Specifying the [limits](#limits) can help protect your site against denial of se - `files` -- set to the maximum number of files per request - `fields` -- set to the maximum number of text fields per request - `fieldNestingDepth` -- set to the minimum depth your field names require (e.g. `3` for `a[b][c]`) +- `fieldArrayIndexLimit` -- set to the largest array index your field names require (e.g. `100` for `a[99]`) ## Manejo de errores Cuando se encuentra un error, Multer delegará el error a Express. You can -display a nice error page using [the standard express way](/guide/error-handling). +display a nice error page using [the standard express way](/guide/error-handling/). Si quieres capturar errores específicamente desde Multer, puedes llamar a la función de Middleware por ti mismo. También, si quieres atrapar sólo [los errores de Multer](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), puedes usar la clase `MulterError` que está adjunta al objeto `multer` en sí mismo (e. . `err instanceof multer.MulterError`). +Multer errors carry a `code` (e.g. `LIMIT_FILE_SIZE`) and, when the error concerns +a specific field, its name in `field`. Errors about a specific file +(`LIMIT_FILE_SIZE`, `LIMIT_UNEXPECTED_FILE`) also expose the client-supplied file +name in `filename`; treat it as untrusted input, like `file.originalname`. + ```javascript const multer = require('multer'); const upload = multer().single('avatar'); @@ -367,5 +427,5 @@ Para obtener información sobre cómo construir tu propio motor de almacenamient [MIT](https://github.com/expressjs/multer/blob/HEAD/LICENSE) [npm-url]: https://npmjs.org/paquete/multer -[insignia osf-scorecard-scorecard-]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[visualizador-escorecard-ossf]: 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/es/resources/middleware/serve-favicon.mdx b/src/content/pages/es/resources/middleware/serve-favicon.mdx index 820836a258..72fcdbe8df 100644 --- a/src/content/pages/es/resources/middleware/serve-favicon.mdx +++ b/src/content/pages/es/resources/middleware/serve-favicon.mdx @@ -139,5 +139,5 @@ server.listen(3000); [descarga-url]: https://npmjs.org/package/serve-favicon [npm-url]: https://npmjs.org/package/serve-favicon -[insignia osf-scorecard-scorecard-]: https://api.scorecard.dev/projects/github.com/expressjs/serve-favicon/badge -[visualizador-escorecard-ossf]: 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/es/resources/middleware/serve-index.mdx b/src/content/pages/es/resources/middleware/serve-index.mdx index 50c1b0483b..c8dc716234 100644 --- a/src/content/pages/es/resources/middleware/serve-index.mdx +++ b/src/content/pages/es/resources/middleware/serve-index.mdx @@ -52,7 +52,7 @@ Serve index acepta estas propiedades en el objeto de opciones. ##### filtro -Aplicar esta función de filtro a archivos. Por defecto es `false`. La función `filter` +Aplicar esta función de filtro a archivos. Defaults to `false`. La función `filter` es llamada para cada archivo, con la firma `filename, índice, archivos, dir)` donde `filename` es el nombre del archivo, `index` es el índice de matriz, `files` es el array de archivos y `dir` es la ruta absoluta que se encuentra el archivo (y por lo tanto, @@ -60,11 +60,11 @@ para el directorio para el que se encuentra la lista). ##### hidden -Mostrar archivos ocultos (puntos). Por defecto es `false`. +Mostrar archivos ocultos (puntos). Defaults to `false`. ##### iconos -Mostrar iconos. Por defecto es `false`. +Mostrar iconos. Defaults to `false`. ##### stylesheet @@ -149,8 +149,8 @@ app.listen(3000); ## Licencia -[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). Los iconos [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) -son creados por/derechos de autor de [FAMFAMFAM](https://web.archive.org/web/20251120154741/http://www.famfamfam.com/). +[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). The [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) icons +are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20230109095739/http://www.famfamfam.com/). [url de appveyor]: https://ci.appveyor.com/project/dougwilson/serve-index [descarga-url]: https://npmjs.org/paquete/serve-index diff --git a/src/content/pages/es/resources/middleware/session.mdx b/src/content/pages/es/resources/middleware/session.mdx index 8782f362d2..a7a14d0c30 100644 --- a/src/content/pages/es/resources/middleware/session.mdx +++ b/src/content/pages/es/resources/middleware/session.mdx @@ -127,8 +127,8 @@ definida en el objeto es la que se utiliza. ##### cookie.particionado -Especifica el valor `boolean` para el atributo [`Partitioned` `Set-Cookie`](https://github.com/expressjs/session/blob/HEAD/rfc-cutler-httpbis-partitioned-cookies) -. Cuando sea verdadero, se establece el atributo `Partitioned`, de lo contrario no lo es. +Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`][rfc-cutler-httpbis-partitioned-cookies] +attribute. Cuando sea verdadero, se establece el atributo `Partitioned`, de lo contrario no lo es. Por defecto, el atributo `Partitioned` no está establecido. **Note** This is an attribute that has not yet been fully standardized, and may @@ -142,6 +142,12 @@ Puede encontrar más información en [la propuesta](https://github.com/privacycg Especifica el valor de `Path` `Set-Cookie`. Por defecto, esto se establece en `'/'`, que es la ruta raíz del dominio. +Since 1.19.1, path matching follows [RFC 6265 section 5.1.4][rfc-6265-5.1.4]. This means +the session middleware will only activate when the request path is an exact match or falls +under a segment boundary of the cookie path. For example, a cookie path of `/admin` will +match `/admin` and `/admin/users` but will **not** match `/administrator`. Prior versions +used a simple prefix check that did not enforce segment boundaries. + ##### cookie.priority Especifica que la `cadena` sea el valor para el [`Priority` atributo `Set-Cookie`][rfc-west-cookie-priority-00-4.1]. @@ -1001,6 +1007,7 @@ En Windows, use el comando correspondiente; [MIT](https://github.com/expressjs/session/blob/HEAD/LICENSE) +[rfc-6265-5.1.4]: https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 [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-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/ [rfc-west-cookie-prioridad-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1 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 3f991f2df4..3f2c16ed61 100644 --- a/src/content/pages/fr/advanced/best-practice-security.mdx +++ b/src/content/pages/fr/advanced/best-practice-security.mdx @@ -48,7 +48,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) { @@ -286,7 +286,7 @@ $ snyk test Keep an eye out for [GitHub Advisory Database](https://github.com/advisories?query=ecosystem%3Anpm) or [Snyk](https://security.snyk.io/vuln/npm) advisories that may affect Express or other modules that your app uses. En général, ces bases de données sont d'excellentes ressources pour la connaissance et les outils sur la sécurité des nœuds. -Enfin, les applications Express—comme toutes les autres applications web—peuvent être vulnérables à diverses attaques sur le Web. Familiarisez-vous avec les [vulnérabilités web connues](https://www.owasp.org/www-project-top-ten/) et prenez des précautions pour les éviter. +Enfin, les applications Express—comme toutes les autres applications web—peuvent être vulnérables à diverses attaques sur le Web. Familiarisez-vous avec les [vulnérabilités web connues](https://owasp.org/www-project-top-ten/) et prenez des précautions pour les éviter. ## Considérations supplémentaires @@ -294,8 +294,8 @@ Voici quelques autres recommandations de l'excellent [Liste de contrôle de séc - Filtrer et nettoyer toujours les entrées de l'utilisateur pour se protéger contre les attaques de script intersite (XSS) et d'injection de commandes. - Protégez contre les attaques d'injection SQL en utilisant des requêtes paramétrées ou des requêtes préparées. -- Utilisez l'outil [sqlmap](http://sqlmap.org/) pour détecter les vulnérabilités d'injection SQL dans votre application. +- Utilisez l'outil [sqlmap](https://sqlmap.org/) pour détecter les vulnérabilités d'injection SQL dans votre application. - Utilisez les outils [nmap](https://nmap.org/) et [sslyze](https://github.com/nabla-c0d3/sslyze) pour tester la configuration de vos codes SSL, , et renégociation ainsi que la validité de votre certificat. -- Utilisez [safe-regex](https://www.npmjs.com/package/safe-regex) pour vous assurer que vos expressions régulières ne sont pas susceptibles d'attaques [déni de service d'expression régulière](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). +- Utilisez [safe-regex](https://www.npmjs.com/package/safe-regex) pour vous assurer que vos expressions régulières ne sont pas susceptibles d'attaques [déni de service d'expression régulière](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS). -[helmet]: https://helmetjs.github.io/ +[helmet]: https://helmet.js.org/ 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/guide/migrating-4.mdx b/src/content/pages/fr/guide/migrating-4.mdx index a8ce458f9e..9597ff7d09 100644 --- a/src/content/pages/fr/guide/migrating-4.mdx +++ b/src/content/pages/fr/guide/migrating-4.mdx @@ -43,133 +43,23 @@ nécessaire pour exécuter votre application. Suivez simplement ces étapes : Le tableau suivant liste les middleware Express 3 et leurs homologues dans Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Express 3Express 4
- express.bodyParser - - body-parser + - multer -
- express.compress - - compression -
- express.cookieSession - - session de cookies -
- express.cookieParser - - analyseur de cookies -
- express.logger - - morgan -
- express.session - - session expresse -
- express.favicon - - favicon service -
- express.responseTime - - temps de réponse -
- express.errorHandler - - errorhandler -
- express.methodOverride - - méthode-override -
- express.timeout - - délai de connexion -
- express.vhost - - vhost -
- express.csrf - - csurf -
- express.directory - - indice de service -
- express.static - - serve-static -
+| Express 3 | Express 4 | +| ------------------------ | ------------------------------------------------------------------------------------------------------- | +| `express.bodyParser` | [body-parser](https://github.com/expressjs/body-parser) + [multer](https://github.com/expressjs/multer) | +| `express.compress` | [compression](https://github.com/expressjs/compression) | +| `express.cookieSession` | [cookie-session](https://github.com/expressjs/cookie-session) | +| `express.cookieParser` | [cookie-parser](https://github.com/expressjs/cookie-parser) | +| `express.logger` | [morgan](https://github.com/expressjs/morgan) | +| `express.session` | [express-session](https://github.com/expressjs/session) | +| `express.favicon` | [serve-favicon](https://github.com/expressjs/serve-favicon) | +| `express.responseTime` | [response-time](https://github.com/expressjs/response-time) | +| `express.errorHandler` | [errorhandler](https://github.com/expressjs/errorhandler) | +| `express.methodOverride` | [method-override](https://github.com/expressjs/method-override) | +| `express.timeout` | [connect-timeout](https://github.com/expressjs/timeout) | +| `express.vhost` | [vhost](https://github.com/expressjs/vhost) | +| `express.csrf` | [csurf](https://github.com/expressjs/csurf) | +| `express.directory` | [serve-index](https://github.com/expressjs/serve-index) | +| `express.static` | [serve-static](https://github.com/expressjs/serve-static) | Voici la [liste complète](https://github.com/senchalabs/connect#middleware) du middleware Express 4. @@ -305,79 +195,21 @@ spécifique à la route. Le tableau suivant liste d'autres changements mineurs mais importants dans Express 4 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ObjetDescription
Node.jsExpress 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x.
`http.createServer()` - Le module `http` n'est plus nécessaire, à moins que vous ayez besoin de travailler directement - avec lui (socket.io/SPDY/HTTPS). L'application peut être démarrée en utilisant la fonction - `app.listen()`. -
`app.configure()` - La fonction `app.configure()` a été supprimée. Utilisez la fonction `process.env.NODE_ENV` ou - `app.get('env')` pour détecter l'environnement et configurer l'application en conséquence. -
`json spaces` - La propriété `json spaces` de l'application est désactivée par défaut dans Express 4. -
`req.accepted()` - Utilisez `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, et - `req.acceptsLanguages()`. -
`res.location()`Ne résout plus les URL relatives.
`req.params`A été un tableau ; maintenant un objet.
`res.locals`Était une fonction ; maintenant un objet.
`res.headerSent`Changé en `res.headersSent`.
`app.route`Maintenant disponible en tant que `app.mountpath`.
`res.on('header')`Supprimé.
`res.charset`Supprimé.
`res.setHeader('Set-Cookie', val)` - La fonctionnalité est maintenant limitée à définir la valeur de base des cookies. Utilisez - `res.cookie()` pour ajouter une fonctionnalité . -
+| Object | Libellé | +| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Node.js | Express 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x. | +| `http.createServer()` | The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). L'application peut être démarrée en utilisant la fonction `app.listen()`. | +| `app.configure()` | La fonction `app.configure()` a été supprimée. Utilisez la fonction `process.env.NODE_ENV` ou `app.get('env')` pour détecter l'environnement et configurer l'application en conséquence. | +| `json spaces` | La propriété `json spaces` de l'application est désactivée par défaut dans Express 4. | +| `req.accepted()` | Utilisez `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, et `req.acceptsLanguages()`. | +| `res.location()` | No longer resolves relative URLs. | +| `req.params` | Was an array; now an object. | +| `res.locals` | Was a function; now an object. | +| `res.headerSent` | Changed to `res.headersSent`. | +| `app.route` | Now available as `app.mountpath`. | +| `res.on('header')` | Removed. | +| `res.charset` | Removed. | +| `res.setHeader('Set-Cookie', val)` | La fonctionnalité est maintenant limitée à définir la valeur de base des cookies. Use `res.cookie()` for added functionality. | ## Exemple de migration d'applications diff --git a/src/content/pages/fr/resources/middleware/body-parser.mdx b/src/content/pages/fr/resources/middleware/body-parser.mdx index cf258e8b43..3fb1c723ef 100644 --- a/src/content/pages/fr/resources/middleware/body-parser.mdx +++ b/src/content/pages/fr/resources/middleware/body-parser.mdx @@ -44,6 +44,10 @@ Ce module fournit les analyseurs suivants : - [Analyseur de corps de texte](#bodyparsertextoptions) - (#bodyparserurlencodedoptions) +All parsers support automatic inflation of `gzip`, `br` (brotli), `deflate` +and `zstd` encodings. `zstd` is available in Node.js `^22.15.0` and +`>=23.8.0`. + Autres analyseurs de corps qui pourraient vous intéresser: - [body](https://www.npmjs.com/package/body#readme) @@ -84,9 +88,8 @@ Les différentes erreurs retournées par ce module sont décrites dans la sectio ### bodyParser.json([options]) Retourne un middleware qui n'analyse que `json` et ne regarde que les requêtes où -l'en-tête `Content-Type` correspond à l'option `type`. Cet analyseur accepte tout encodage -Unicode du corps et supporte l'inflation automatique des encodages `gzip`, -`br` (brotli) et `deflate`. +l'en-tête `Content-Type` correspond à l'option `type`. This parser accepts any +Unicode encoding of the body. Un nouvel objet `body` contenant les données analysées est peuplé sur l'objet `request` après le middleware (c'est-à-dire `req.body`). @@ -146,9 +149,7 @@ de la requête. L'analyse peut être annulée en lançant une erreur. ### bodyParser.raw([options]) Retourne un middleware qui analyse tous les corps comme un `Buffer` et regarde seulement les requêtes -où l'en-tête `Content-Type` correspond à l'option `type`. Cet analyseur -supporte l'inflation automatique des encodages `gzip`, `br` (brotli) et `deflate` -. +où l'en-tête `Content-Type` correspond à l'option `type`. Un nouvel objet `body` contenant les données analysées est peuplé sur l'objet `request` après le middleware (c'est-à-dire `req.body`). Ce sera un objet `Buffer` @@ -194,23 +195,21 @@ de la requête. L'analyse peut être annulée en lançant une erreur. ### bodyParser.text([options]) Retourne un middleware qui analyse tous les corps comme une chaîne de caractères et ne regarde que les requêtes -où l'en-tête `Content-Type` correspond à l'option `type`. Cet analyseur -supporte l'inflation automatique des encodages `gzip`, `br` (brotli) et `deflate` -. +où l'en-tête `Content-Type` correspond à l'option `type`. -Une nouvelle chaîne `body` contenant les données analysées est remplie sur l'objet `request` -après le middleware (c'est-à-dire `req.body`). Ce sera une chaîne du corps -. +A new `body` string containing the parsed data is populated on the `request` +object after the middleware (i.e. `req.body`). This will be a string of the +body. #### Options -La fonction `text` prend un objet optionnel `options` qui peut contenir n'importe laquelle de -des clés suivantes : +The `text` function takes an optional `options` object that may contain any of +the following keys: ##### Charset par défaut -Spécifie le jeu de caractères par défaut pour le contenu du texte si le jeu de caractères n'est pas -spécifié dans l'en-tête `Content-Type` de la requête. `utf-8` par défaut. +Specify the default character set for the text content if the charset is not +specified in the `Content-Type` header of the request. `utf-8` par défaut. ##### gonfler @@ -229,13 +228,13 @@ est `'100kb'`. ##### Type de type The `type` option is used to determine what media type the middleware will -parse. Cette option peut être une chaîne, un tableau de chaînes de caractères ou une fonction. Si pas -une fonction, L'option `type` est passée directement à la bibliothèque -[type-is](https://www.npmjs.com/package/type-is#readme) et peut -être un nom d'extension (comme `txt`), un type MIME (comme `text/plain`), ou un type MIME -avec un caractère générique (comme `*/*` ou `text/*`). Si une fonction, l'option `type` -est appelée comme `fn(req)` et la requête est analysée si elle renvoie une valeur truthy -. `text/plain` par défaut. +parse. Cette option peut être une chaîne, un tableau de chaînes de caractères ou une fonction. If not +a function, `type` option is passed directly to the +[type-is](https://www.npmjs.com/package/type-is#readme) library and this can +be an extension name (like `txt`), a mime type (like `text/plain`), or a mime +type with a wildcard (like `*/*` or `text/*`). If a function, the `type` +option is called as `fn(req)` and the request is parsed if it returns a +truthy value. Defaults to `text/plain`. ##### vérifier @@ -245,10 +244,9 @@ de la requête. L'analyse peut être annulée en lançant une erreur. ### bodyParser.urlencoded([options]) -Retourne un middleware qui n'analyse que les corps `urlencoded` et ne regarde que les requêtes -où l'en-tête `Content-Type` correspond à l'option `type`. Cet analyseur -n'accepte que les encodages UTF-8 et ISO-8859-1 du corps et supporte -l'inflation automatique des encodages `gzip`, `br` (brotli) et `deflate`. +Returns middleware that only parses `urlencoded` bodies and only looks at +requests where the `Content-Type` header matches the `type` option. This +parser accepts only UTF-8 and ISO-8859-1 encodings of the body. Un nouvel objet `body` contenant les données analysées est peuplé sur l'objet `request` après le middleware (c'est-à-dire `req.body`). This object will contain @@ -257,17 +255,17 @@ key-value pairs, where the value can be a string or array (when `extended` is #### Options -La fonction `urlencoded` prend un objet optionnel `options` qui peut contenir -l'une des clés suivantes : +The `urlencoded` function takes an optional `options` object that may contain +any of the following keys: -##### étendu +##### extended -La syntaxe "étendue" permet d'encoder des objets et des tableaux riches dans le format -encodé par une URL, permettant une expérience similaire au JSON avec encodé par une URL. For +The "extended" syntax allows for rich objects and arrays to be encoded into the +URL-encoded format, allowing for a JSON-like experience with URL-encoded. For more information, please see the qs library. -`false` par défaut. +Defaults to `false`. ##### gonfler @@ -285,21 +283,21 @@ est `'100kb'`. ##### parameterLimit -L'option `parameterLimit` contrôle le nombre maximum de paramètres que -sont autorisés dans les données encodées en URL. Si une requête contient plus de paramètres -que cette valeur, un 413 sera retourné au client. Par défaut, `1000`. +The `parameterLimit` option controls the maximum number of parameters that +are allowed in the URL-encoded data. If a request contains more parameters +than this value, a 413 will be returned to the client. Defaults to `1000`. ##### Type de type The `type` option is used to determine what media type the middleware will -parse. Cette option peut être une chaîne, un tableau de chaînes de caractères ou une fonction. Si pas -une fonction, L'option `type` est passée directement à la bibliothèque -[type-is](https://www.npmjs.com/package/type-is#readme) et peut -être un nom d'extension (comme `urlencoded`), un type mime (comme -`application/x-www-form-urlencoded`), ou un type mime avec un caractère générique (comme -`*/x-www-form-urlencoded`). Si une fonction, l'option `type` est appelée en tant que -`fn(req)` et la requête est analysée si elle renvoie une valeur vraie. Par défaut, -est `application/x-www-form-urlencoded`. +parse. Cette option peut être une chaîne, un tableau de chaînes de caractères ou une fonction. If not +a function, `type` option is passed directly to the +[type-is](https://www.npmjs.com/package/type-is#readme) library and this can +be an extension name (like `urlencoded`), a mime type (like +`application/x-www-form-urlencoded`), or a mime type with a wildcard (like +`*/x-www-form-urlencoded`). If a function, the `type` option is called as +`fn(req)` and the request is parsed if it returns a truthy value. Defaults +to `application/x-www-form-urlencoded`. ##### vérifier @@ -309,131 +307,131 @@ de la requête. L'analyse peut être annulée en lançant une erreur. ##### Charset par défaut -Le jeu de caractères par défaut à analyser, s'il n'est pas spécifié dans le type de contenu. Must be +The default charset to parse as, if not specified in content-type. Must be either `utf-8` or `iso-8859-1`. `utf-8` par défaut. ##### charsetSentinel -Si vous voulez laisser la valeur du paramètre `utf8` prendre la priorité en tant que sélecteur de jeu de caractères -. Il faut que le formulaire contienne un paramètre nommé `utf8` avec une valeur -de `✓`. `false` par défaut. +Whether to let the value of the `utf8` parameter take precedence as the charset +selector. It requires the form to contain a parameter named `utf8` with a value +of `✓`. Defaults to `false`. -##### Interpréter des entités numériques +##### interpretNumericEntities -S'il faut décoder des entités numériques telles que `☺` lors de l'analyse d'un formulaire iso-8859-1 -. `false` par défaut. +Whether to decode numeric entities such as `☺` when parsing an iso-8859-1 +form. Defaults to `false`. -##### profondeur +##### depth -L'option `depth` est utilisée pour configurer la profondeur maximale de la bibliothèque `qs` lorsque `extended` est `true`. Cela vous permet de limiter le nombre de clés qui sont analysées et peuvent être utiles pour prévenir certains types d'abus. Par défaut, `32`. Il est recommandé de garder cette valeur aussi basse que possible. +The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible. -## Erreurs +## Errors -Les middlewares fournis par ce module créent des erreurs en utilisant le module -[`http-errors`](https://www.npmjs.com/package/http-errors). Les erreurs -auront généralement une propriété `status`/`statusCode` qui contient le code de réponse HTTP -suggéré. une propriété `expose` pour déterminer si la propriété `message` -doit être affichée au client, une propriété `type` pour déterminer le type d'erreur -sans correspondre au `message`, et une propriété `body` contenant -le corps lu, si disponible. +The middlewares provided by this module create errors using the +[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors +will typically have a `status`/`statusCode` property that contains the suggested +HTTP response code, an `expose` property to determine if the `message` property +should be displayed to the client, a `type` property to determine the type of +error without matching against the `message`, and a `body` property containing +the read body, if available. -Les erreurs suivantes sont les plus courantes créées, bien que toute erreur puisse passer par -pour diverses raisons. +The following are the common errors created, though any error can come through +for various reasons. -### encodage de contenu non pris en charge +### content encoding unsupported -Cette erreur se produira lorsque la requête a eu un en-tête `Content-Encoding` que -contenait un encodage, mais l'option "inflation" a été définie à `false`. La propriété -`status` est définie à `415`, la propriété `type` est définie à -`'encodage. nsupported'`, et la propriété `charset` sera définie à l'encodage -qui n'est pas pris en charge. +This error will occur when the request had a `Content-Encoding` header that +contained an encoding but the "inflation" option was set to `false`. The +`status` property is set to `415`, the `type` property is set to +`'encoding.unsupported'`, and the `charset` property will be set to the +encoding that is unsupported. -### l'analyse de l'entité a échoué +### entity parse failed -Cette erreur se produira lorsque la requête contenait une entité qui ne pouvait pas être -analysée par le middleware. La propriété `status` est définie à `400`, la propriété `type` -est définie à `'entity.parse. ailed'`, et la propriété `body` est définie à -la valeur de l'entité qui a échoué l'analyse. +This error will occur when the request contained an entity that could not be +parsed by the middleware. The `status` property is set to `400`, the `type` +property is set to `'entity.parse.failed'`, and the `body` property is set to +the entity value that failed parsing. -### échec de la vérification de l'entité +### entity verify failed -Cette erreur se produira lorsque la requête contenait une entité qui ne pouvait pas être -échec de la vérification par l'option définie `verify`. La propriété `status` est -définie à `403`, la propriété `type` est définie à `'entity.verify. ailed'`, et la propriété -`body` est définie à la valeur de l'entité qui a échoué à la vérification. +This error will occur when the request contained an entity that could not be +verified by the defined `verify` option. The `status` property is +set to `403`, the `type` property is set to `'entity.verify.failed'`, and the +`body` property is set to the entity value that failed verification. -### demande abandonnée +### request aborted -Cette erreur se produira lorsque la requête sera annulée par le client avant de lire -le corps est terminé. La propriété `received` sera définie sur le nombre de -octets reçus avant que la requête ne soit annulée et la propriété `expected` est -définie sur le nombre d'octets attendus. La propriété `status` est définie à `400` -et la propriété `type` est définie à `'request.aborted'`. +This error will occur when the request is aborted by the client before reading +the body has finished. The `received` property will be set to the number of +bytes received before the request was aborted and the `expected` property is +set to the number of expected bytes. The `status` property is set to `400` +and `type` property is set to `'request.aborted'`. -### requête d'entité trop grande +### request entity too large -Cette erreur se produira lorsque la taille du corps de la requête est plus grande que l'option "limite" -. La propriété `limit` sera définie à la limite d'octets et la propriété `length` -sera définie à la longueur du corps de la requête. La propriété `status` est -définie à `413` et la propriété `type` est définie à `'entity.too.large'`. +This error will occur when the request body's size is larger than the "limit" +option. The `limit` property will be set to the byte limit and the `length` +property will be set to the request body's length. The `status` property is +set to `413` and the `type` property is set to `'entity.too.large'`. -### la taille de la requête ne correspond pas à la longueur du contenu +### request size did not match content length -Cette erreur se produira lorsque la longueur de la requête ne correspond pas à la longueur de -l'en-tête `Content-Length`. Cela se produit généralement lorsque la requête est mal formée, -généralement lorsque l'en-tête `Content-Length` a été calculé en se basant sur les caractères -au lieu d'octets. La propriété `status` est définie à `400` et la propriété `type` -est définie à `'request.size.invalid'`. +This error will occur when the request's length did not match the length from +the `Content-Length` header. This typically occurs when the request is malformed, +typically when the `Content-Length` header was calculated based on characters +instead of bytes. The `status` property is set to `400` and the `type` property +is set to `'request.size.invalid'`. -### l'encodage du flux ne doit pas être défini +### stream encoding should not be set -Cette erreur se produira lorsque quelque chose a appelé la méthode `req.setEncoding` avant -à ce middleware. This module operates directly on bytes only and you cannot -call `req.setEncoding` when using this module. La propriété `status` est définie à -`500` et la propriété `type` est définie à `'stream.encoding.set'`. +This error will occur when something called the `req.setEncoding` method prior +to this middleware. This module operates directly on bytes only and you cannot +call `req.setEncoding` when using this module. The `status` property is set to +`500` and the `type` property is set to `'stream.encoding.set'`. -### le flux n'est pas lisible +### stream is not readable -Cette erreur se produira lorsque la requête ne sera plus lisible lorsque ce middleware -tentera de la lire. Cela signifie généralement quelque chose d'autre qu'un middleware de -ce module a déjà lu le corps de la requête et le middleware a également été configuré en -lisant la même requête. La propriété `status` est définie à `500` et la propriété `type` -est définie à `'stream.not.readable'`. +This error will occur when the request is no longer readable when this middleware +attempts to read it. This typically means something other than a middleware from +this module read the request body already and the middleware was also configured to +read the same request. The `status` property is set to `500` and the `type` +property is set to `'stream.not.readable'`. -### trop de paramètres +### too many parameters -Cette erreur se produira lorsque le contenu de la requête dépassera la -`parameterLimit` configurée pour l'analyseur `urlencoded`. La propriété `status` est définie à -`413` et la propriété `type` est définie à `'parameters.too.many'`. +This error will occur when the content of the request exceeds the configured +`parameterLimit` for the `urlencoded` parser. The `status` property is set to +`413` and the `type` property is set to `'parameters.too.many'`. -### jeu de caractères "BOGUS" non pris en charge +### unsupported charset "BOGUS" -Cette erreur se produira lorsque la requête aura un paramètre charset dans l'en-tête -`Content-Type`, mais le module `iconv-lite` ne le supporte pas OU l'analyseur -ne le supporte pas. Le jeu de caractères est contenu dans le message ainsi que -comme dans la propriété `charset`. La propriété `status` est définie à `415`, la propriété -`type` est définie à `'charset. nsupported'`, et la propriété `charset` -est définie au jeu de caractères qui n'est pas pris en charge. +This error will occur when the request had a charset parameter in the +`Content-Type` header, but the `iconv-lite` module does not support it OR the +parser does not support it. The charset is contained in the message as well +as in the `charset` property. The `status` property is set to `415`, the +`type` property is set to `'charset.unsupported'`, and the `charset` property +is set to the charset that is unsupported. -### encodage de contenu non pris en charge "bogus" +### unsupported content encoding "bogus" This error will occur when the request had a `Content-Encoding` header that -contained an unsupported encoding. L'encodage est contenu dans le message -ainsi que dans la propriété `encoding`. La propriété `status` est définie à `415`, -la propriété `type` est définie à `'encoding. nsupported'`, et la propriété `encoding` -est définie à l'encodage qui n'est pas pris en charge. +contained an unsupported encoding. The encoding is contained in the message +as well as in the `encoding` property. The `status` property is set to `415`, +the `type` property is set to `'encoding.unsupported'`, and the `encoding` +property is set to the encoding that is unsupported. -### L'entrée a dépassé la profondeur +### The input exceeded the depth -Cette erreur se produit lors de l'utilisation de `bodyParser.urlencoded` avec la propriété `extended` définie à `true` et l'entrée dépasse l'option `depth` configurée. La propriété `status` est définie à `400`. Il est recommandé d'examiner l'option `depth` et d'évaluer si elle nécessite une valeur plus élevée. Lorsque l'option `depth` est définie à `32` (valeur par défaut), l'erreur ne sera pas levée. +This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown. ## Exemples -### Rapide/Connecter générique de premier niveau +### Express/Connect top-level generic -Cet exemple démontre l'ajout d'un analyseur générique JSON et encodé en URL comme un middleware de premier niveau -qui va analyser le corps de toutes les requêtes entrantes. -C'est la configuration la plus simple. +This example demonstrates adding a generic JSON and URL-encoded parser as a +top-level middleware, which will parse the bodies of all incoming requests. +This is the simplest setup. ```js const express = require('express'); @@ -454,10 +452,10 @@ app.use(function (req, res) { }); ``` -### Spécifique à la route Express +### Express route-specific -Cet exemple démontre l'ajout d'analyseurs de corps spécifiquement aux routes dont -a besoin. En général, c'est le moyen le plus recommandé d'utiliser l'analyseur de corps avec +This example demonstrates adding body parsers specifically to the routes that +need them. In general, this is the most recommended way to use body-parser with Express. ```js @@ -485,10 +483,10 @@ app.post('/api/users', jsonParser, function (req, res) { }); ``` -### Changer le type accepté pour les analyseurs +### Change accepted type for parsers -Tous les analyseurs acceptent une option `type` qui vous permet de changer le -`Content-Type` que le middleware va analyser. +All the parsers accept a `type` option which allows you to change the +`Content-Type` that the middleware will parse. ```js const express = require('express'); @@ -511,5 +509,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 -[badge ossf-scorecard]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge -[visualiseur-scorecard-ossf]: 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/fr/resources/middleware/compression.mdx b/src/content/pages/fr/resources/middleware/compression.mdx index e46852e404..ec213da492 100644 --- a/src/content/pages/fr/resources/middleware/compression.mdx +++ b/src/content/pages/fr/resources/middleware/compression.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -21,13 +21,13 @@ Les codages de compression suivants sont pris en charge : - gzip - br (brotli) -**Note** Brotli n'est supporté que depuis les versions de Node.js v11.7.0 et v10.16.0. +**Note** Brotli is available in all currently supported Node.js LTS versions (v18+). ## Installer Ceci est un module [Node.js](https://nodejs.org/en/) disponible via [npm registry](https://www.npmjs.com/). L'installation se fait à l'aide de la commande -[`npm install`](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): +[`npm install`](https://docs.npmjs.com/downloading-and-installing-packages-locally): @@ -304,7 +304,7 @@ Le projet Express.js salue toutes les contributions constructives. Les contribut du code pour les corrections de bugs et les améliorations, aux ajouts et corrections à la documentation, tests supplémentaires, triant les demandes de fusion entrantes et les problèmes, et plus encore ! -Voir le [Guide de contribution] (https://github.com/expressjs/express/blob/master/Contributing.md) pour plus de détails techniques sur la contribution. +See the [Contributing Guide](https://github.com/expressjs/.github/blob/HEAD/CONTRIBUTING.md) for more technical details on contributing. ## Licence @@ -312,6 +312,6 @@ Voir le [Guide de contribution] (https://github.com/expressjs/express/blob/maste [npm-url]: https://npmjs.org/package/compression [downloads-url]: https://npmcharts.com/compare/compression?minimal=true -[badge ossf-scorecard]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge -[visualiseur-scorecard-ossf]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression +[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 [url de financement]: https://opencollective.com/exprès diff --git a/src/content/pages/fr/resources/middleware/morgan.mdx b/src/content/pages/fr/resources/middleware/morgan.mdx index 6da011970a..a0981a95d7 100644 --- a/src/content/pages/fr/resources/middleware/morgan.mdx +++ b/src/content/pages/fr/resources/middleware/morgan.mdx @@ -8,14 +8,14 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; middleware de l'enregistreur de requêtes HTTP pour node.js -> Nommer après [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), une série que vous ne devriez pas regarder jusqu'à la fin. +> Named after [Dexter](https://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. ## Installation @@ -35,6 +35,16 @@ Ceci est un module [Node.js](https://nodejs.org/en/) disponible via ## API +For ES Modules: + +{/* eslint-disable no-unused-vars */} + +```js +import morgan from 'morgan'; +``` + +For CommonJS: + {/* eslint-disable no-unused-vars */} ```js @@ -78,10 +88,12 @@ morgan(function (tokens, req, res) { tokens.method(req, res), tokens.url(req, res), tokens.status(req, res), - tokens.res(req, res, 'content-length'), '-', - tokens['response-time'](https://github.com/expressjs/morgan/blob/HEAD/req, res), 'ms' - ].join(' ') -}) + tokens.res(req, res, 'content-length'), + '-', + tokens['response-time'](req, res), + 'ms', + ].join(' '); +}); ``` #### Options @@ -90,9 +102,9 @@ Morgan accepte ces propriétés dans l'objet options. ##### immédiat -Écrivez la ligne du journal sur la requête au lieu de la réponse. Cela signifie qu'une requête -sera enregistrée même si le serveur plante, _mais les données de la réponse (comme le code de réponse -, la longueur du contenu, etc.) ne peut pas être logged_. +Écrivez la ligne du journal sur la requête au lieu de la réponse. This means that requests will +be logged even if the server crashes, _but data from the response (like the +response code, content length, etc.) ne peut pas être logged_. ##### sauter @@ -114,6 +126,33 @@ morgan('combined', { Flux de sortie pour l'écriture des lignes de log, la valeur par défaut est `process.stdout`. +If the stream is in object mode (`stream.writableObjectMode` is `true`) and the +format function returns an object, the object is written to the stream as-is, +without a trailing newline. This allows passing structured log entries to +loggers that accept objects: + +{/* eslint-disable no-undef */} + +```js +morgan( + function (tokens, req, res) { + return { + method: tokens.method(req, res), + url: tokens.url(req, res), + status: Number(tokens.status(req, res)), + }; + }, + { + stream: { + writableObjectMode: true, + write: function (entry) { + // entry is the object returned by the format function + }, + }, + } +); +``` + #### Formats prédéfinis Il existe différents formats prédéfinis fournis : @@ -151,6 +190,11 @@ sans couleur pour les codes d'information. GET /dev 200 0.224 ms - 2 ``` +Coloring is disabled when the [`NO_COLOR`](https://no-color.org) environment +variable is set to any non-empty value, in which case the output above is +written without any escape sequences. The variable is read once, when `morgan` +is first required. + ##### court Plus court que la valeur par défaut, y compris le temps de réponse. @@ -191,8 +235,8 @@ Appeler `morgan.token()` en utilisant le même nom qu'un jeton existant écraser . La fonction token est appelée avec les arguments `req` et `res`, représentant -la requête HTTP et la réponse HTTP. De plus, le jeton peut accepter d'autres arguments de -il choisit de personnaliser le comportement. +la requête HTTP et la réponse HTTP. Additionally, the token can accept further arguments of +its choosing to customize behavior. ##### :date[format] @@ -218,7 +262,7 @@ L'ID de processus du processus Node.js gérant la requête. ##### -L'en-tête Référent de la requête. Cela utilisera l'en-tête standard de Referer mal orthographié s'il existe, sinon Referrer. +L'en-tête Référent de la requête. This will use the standard mis-spelled Referer header if it exists, otherwise Referrer. ##### :remote-addr @@ -264,7 +308,7 @@ inclus sur le nombre, par défaut à `3`, qui fournit une précision de microsec ##### -L'URL de la requête. Cela utilisera `req.originalUrl` si existe, sinon `req.url`. +L'URL de la requête. This will use `req.originalUrl` if it exists, otherwise `req.url`. ##### :user-agent @@ -274,13 +318,13 @@ Le contenu de l'en-tête User-Agent de la requête. Compiler une chaîne de format dans une fonction `format` pour l'utiliser par `morgan`. Une chaîne de format est une chaîne de caractères qui représente une seule ligne de log et peut utiliser la syntaxe des jetons. -Les jetons sont des références par `:token-name`. If tokens accept arguments, they can +Tokens are referenced by `:token-name`. If tokens accept arguments, they can be passed using `[]`, for example: `:token-name[pretty]` would pass the string `'pretty'` as an argument to the token `token-name`. -La fonction retournée par `morgan. ompile` prend trois arguments `tokens`, `req`, et -`res`, où `tokens` est un objet avec tous les tokens définis, `req` est la requête HTTP et -`res` est la réponse HTTP. La fonction retournera une chaîne qui sera la ligne de log, +The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and +`res`, where `tokens` is an object with all defined tokens, `req` is the HTTP request and +`res` is the HTTP response. La fonction retournera une chaîne qui sera la ligne de log, ou `undefined` / `null` pour sauter la journalisation. Normally formats are defined using `morgan.format(name, format)`, but for certain @@ -290,7 +334,7 @@ advanced uses, this compile function is directly available. ### express/connexion -Exemple d'application qui va enregistrer toutes les requêtes dans le format combiné Apache au STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var express = require('express'); @@ -307,7 +351,7 @@ app.get('/', function (req, res) { ### serveur http vanilla -Exemple d'application qui va enregistrer toutes les requêtes dans le format combiné Apache au STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var finalhandler = require('finalhandler'); @@ -431,7 +475,7 @@ Exemple d'application qui utilisera des formats de jetons personnalisés. Cela a ```js var express = require('express'); var morgan = require('morgan'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); morgan.token('id', function getId(req) { return req.id; diff --git a/src/content/pages/fr/resources/middleware/multer.mdx b/src/content/pages/fr/resources/middleware/multer.mdx index c111525a27..cd83d5159f 100644 --- a/src/content/pages/fr/resources/middleware/multer.mdx +++ b/src/content/pages/fr/resources/middleware/multer.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -18,23 +18,6 @@ au-dessus de [busboy](https://github.com/mscdex/busboy) pour une efficacité max **REMARQUE** : Multer ne traitera aucun formulaire qui n'est pas multipartie (`multipart/form-data`). -## Traductions - -Ce README est également disponible dans d'autres langues : - -| | | -| ------------------------------------------------------------------------------- | -------------- | -| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabe | -| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinois | -| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | Français | -| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Coréen | -| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portugais (BR) | -| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russe | -| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Espagnol | -| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek | -| [Vie\ 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) | Turc | - ## Installation @@ -130,23 +113,26 @@ app.post('/stats', upload.single('uploaded_file'), function (req, res) { }); ``` +Complete client-side and server-side examples (browser `FormData` uploads of a +blob and of an image) are in the [`examples/`](https://github.com/expressjs/multer/blob/HEAD/examples/) folder. + ## API ### Informations sur le fichier Chaque fichier contient les informations suivantes : -| Clés | Libellé | Note | -| ------------- | -------------------------------------------------- | ------------------ | -| `nomdechamp` | Nom du champ spécifié dans le formulaire | | -| `nomoriginal` | Nom du fichier sur l'ordinateur de l'utilisateur | | -| `encodage` | Type d'encodage du fichier | | -| `mimetype` | Type Mime du fichier | | -| `size` | Taille du fichier en octets | | -| `destination` | Le dossier dans lequel le fichier a été sauvegardé | `DiskStorage` | -| `filename` | Le nom du fichier dans la `destination` | `DiskStorage` | -| `path` | Le chemin complet vers le fichier téléchargé | `DiskStorage` | -| `tampon` | Un `Buffer` du fichier entier | `Stockage mémoire` | +| Clés | Libellé | Note | +| ------------- | ----------------------------------------------------------------------------------- | ------------------ | +| `nomdechamp` | Nom du champ spécifié dans le formulaire | | +| `nomoriginal` | Name of the file on the user's computer, or the full path when `preservePath: true` | | +| `encodage` | Type d'encodage du fichier | | +| `mimetype` | Type Mime du fichier | | +| `size` | Taille du fichier en octets | | +| `destination` | Le dossier dans lequel le fichier a été sauvegardé | `DiskStorage` | +| `filename` | Le nom du fichier dans la `destination` | `DiskStorage` | +| `path` | Le chemin complet vers le fichier téléchargé | `DiskStorage` | +| `tampon` | Un `Buffer` du fichier entier | `Stockage mémoire` | ### `multer(opts)` @@ -161,11 +147,15 @@ Voici les options qui peuvent être passées à Multer. | Clés | Libellé | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `defCharset` | Default character set to use for text field values that do not declare one. Default: `'utf8'` | +| `defParamCharset` | Le jeu de caractères par défaut à utiliser pour les valeurs des paramètres de l'en-tête de la partie (par exemple le nom du fichier) qui ne sont pas des paramètres étendus (contenant un jeu de caractères explicite). Par défaut: `'latin1'` | | `dest` ou `storage` | Où stocker les fichiers | | `fileFilter` | Fonction pour contrôler quels fichiers sont acceptés | +| `fileHwm` | `highWaterMark` of each file stream (`file.stream`). Default: busboy's default | +| `highWaterMark` | `highWaterMark` of the multipart parser stream. Default: busboy's default | | `limites` | Limites des données téléchargées | -| `preservePath` | Garder le chemin complet des fichiers au lieu du nom de base | -| `defParamCharset` | Le jeu de caractères par défaut à utiliser pour les valeurs des paramètres de l'en-tête de la partie (par exemple le nom du fichier) qui ne sont pas des paramètres étendus (contenant un jeu de caractères explicite). Par défaut: `'latin1'` | +| `preservePath` | Keep the full client-supplied path in `file.originalname` instead of just the base name | +| `streamHandler` | Function that feeds the request body to busboy; defaults to `req.pipe(busboy)` | Dans une application web moyenne, seul `dest` peut être requis, et configuré comme montré dans l'exemple suivant. @@ -174,6 +164,14 @@ l'exemple suivant. const upload = multer({ dest: 'uploads/' }); ``` +When `preservePath` is enabled, Multer passes the incoming filename through with +any path segments provided by the client. This is exposed as `file.originalname`; +it does not change the destination folder, create directories, or sanitize the +path for you. `file.originalname` is always client-supplied and should be treated +as untrusted; with `preservePath` it additionally contains the path segments the +client sent. Normalize or validate it before using it in a custom `filename` or +storage engine. + Si vous voulez plus de contrôle sur vos envois, vous voudrez utiliser l'option `storage` au lieu de `dest`. Multer est livré avec des moteurs de stockage `DiskStorage` et `MemoryStorage`; Plus de moteurs sont disponibles auprès de tiers. @@ -189,6 +187,9 @@ Accepte un tableau de fichiers, tous avec le nom `fieldname`. Erreur optionnelle plus que les fichiers `maxCount` sont téléchargés. Le tableau de fichiers sera stocké dans `req.files`. +Files skipped by `fileFilter` do not count towards `maxCount`. Use +`limits.files` to bound how many files are read from a request. + #### `.fields(fields)` Accepte un mélange de fichiers, spécifié par `fields`. Un objet avec des tableaux de fichiers @@ -206,12 +207,12 @@ Exemple: #### `.none()` -Accepter uniquement les champs de texte. Si un téléchargement de fichier est effectué, une erreur avec le code -"LIMIT_UNEXPECTED_FILE" sera émise. +Accepter uniquement les champs de texte. If any file upload is made, error with code +`LIMIT_UNEXPECTED_FILE` will be issued. #### `.any()` -Accepte tous les fichiers qui viennent sur le fil. Un tableau de fichiers sera stocké dans +Accepts all files that come over the wire. Un tableau de fichiers sera stocké dans `req.files`. **AVERTISSEMENT :** Assurez-vous de toujours gérer les fichiers qu'un utilisateur téléverse. @@ -226,21 +227,26 @@ où vous gérez les fichiers téléchargés. Le moteur de stockage de disque vous donne un contrôle total sur le stockage des fichiers sur disque. ```javascript +const crypto = require('crypto'); + const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/tmp/my-uploads'); }, filename: function (req, file, cb) { - const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); - cb(null, file.fieldname + '-' + uniqueSuffix); + crypto.randomBytes(16, function (err, raw) { + if (err) return cb(err); + cb(null, file.fieldname + '-' + raw.toString('hex')); + }); }, }); const upload = multer({ storage: storage }); ``` -Il y a deux options disponibles, `destination` et `filename`. Ce sont les deux fonctions -qui déterminent où le fichier doit être stocké. +There are three options available: `destination`, `filename` and `flush`. All of +them except `flush` are functions that determine where the file should be +stored. `destination` is used to determine within which folder the uploaded files should be stored. Cela peut également être donné en tant que `string` (par exemple `'/tmp/uploads'`). Si aucun @@ -268,6 +274,14 @@ Pour comprendre la convention d'appel utilisée dans le callback (avoir besoin d null comme premier paramètre), reportez-vous à [Node. s gestion des erreurs](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors) +`flush` is an optional boolean. When set to `true`, the file data is flushed to +disk with an `fsync` call before the upload handler runs, which prevents data +loss if the process or the system crashes while the data is still sitting in +the operating system's page cache. It is disabled by default because forcing a +disk flush on every upload has a performance cost. Note that this syncs the +file contents only; if the new directory entry must survive a crash as well, +fsync the destination directory yourself. + #### `Stockage mémoire` Le moteur de stockage de mémoire stocke les fichiers en mémoire comme des objets `Buffer`. It @@ -287,20 +301,36 @@ memory storage is used. ### `limites` -Un objet spécifiant les limites de taille des propriétés optionnelles suivantes. Multer passe cet objet directement dans busboy, et les détails des propriétés peuvent être trouvés sur la page [busboy's page](https://github.com/mscdex/busboy#busboy-methods). +Un objet spécifiant les limites de taille des propriétés optionnelles suivantes. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#exports). + +`limits` can also be a function that receives the request and returns such an +object. It is called once per request, before parsing starts, so limits can +depend on e.g. the authenticated user: + +```javascript +const upload = multer({ + limits: function (req) { + return { fileSize: req.user.maxUploadSize }; + }, +}); +``` + +Limits apply to the whole request; there is no per-file limit. To restrict +individual files by type or name, use `fileFilter` or a custom storage engine. Les valeurs entières suivantes sont disponibles : -| Clés | Libellé | Par défaut | -| ------------------- | ------------------------------------------------------------------------------------- | ---------- | -| `fieldNameSize` | Taille maximale du nom du champ | 100 octets | -| `fieldSize` | Taille maximale du champ (en octets) | 1 Mo | -| `champs` | Nombre maximum de champs hors fichier | Infini | -| `fileSize` | Pour les formes multiparties, la taille maximale du fichier (en octets) | Infini | -| `fichiers` | Pour les formulaires en plusieurs parties, le nombre maximum de champs de fichier | Infini | -| `Parties` | Pour les formes multiparties, le nombre maximum de parties (champs + fichiers) | Infini | -| `headerPairs` | Pour les formes multiparties, le nombre maximum de clés d'en-tête =>valeur à analyser | 2000 | -| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infini | +| Clés | Libellé | Par défaut | +| ---------------------- | ------------------------------------------------------------------------------------- | ---------- | +| `fieldNameSize` | Taille maximale du nom du champ | Infini | +| `fieldSize` | Taille maximale du champ (en octets) | 1 Mo | +| `champs` | Nombre maximum de champs hors fichier | Infini | +| `fileSize` | Pour les formes multiparties, la taille maximale du fichier (en octets) | Infini | +| `fichiers` | Pour les formulaires en plusieurs parties, le nombre maximum de champs de fichier | Infini | +| `Parties` | Pour les formes multiparties, le nombre maximum de parties (champs + fichiers) | Infini | +| `headerPairs` | Pour les formes multiparties, le nombre maximum de clés d'en-tête =>valeur à analyser | 2000 | +| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infini | +| `fieldArrayIndexLimit` | Max numeric array index accepted inside a field name (e.g. `a[3]` uses index 3) | Infini | Spécifier les limites peut aider à protéger votre site contre les attaques par déni de service (DoS). @@ -325,6 +355,30 @@ function fileFilter(req, file, cb) { } ``` +### `streamHandler` + +By default Multer reads the request with `req.pipe(busboy)`. Some platforms +consume the request body before your handlers run, so there is nothing left to +pipe. Google Cloud Functions and Firebase Functions, for example, expose the +already-read body as `req.rawBody`. Provide a `streamHandler` to feed busboy +yourself in that case: + +```javascript +const upload = multer({ + storage: multer.memoryStorage(), + streamHandler: function (req, busboy) { + if (req.rawBody) { + busboy.end(req.rawBody); + } else { + req.pipe(busboy); + } + }, +}); +``` + +The function receives the request and the busboy instance and must write the +whole multipart body to busboy and end it. + ## Security Specifying the [limits](#limits) can help protect your site against denial of service (DoS) attacks. The following limits are recommended for most applications: @@ -333,6 +387,7 @@ Specifying the [limits](#limits) can help protect your site against denial of se - `files` -- set to the maximum number of files per request - `fields` -- set to the maximum number of text fields per request - `fieldNestingDepth` -- set to the minimum depth your field names require (e.g. `3` for `a[b][c]`) +- `fieldArrayIndexLimit` -- set to the largest array index your field names require (e.g. `100` for `a[99]`) ## Gestion des erreurs @@ -342,6 +397,11 @@ afficher une belle page d'erreur en utilisant [le type express way](/guide/error Si vous voulez attraper des erreurs spécifiques à Multer, vous pouvez appeler la fonction middleware par vous-même. Aussi, si vous voulez attraper seulement [les erreurs Multer](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), vous pouvez utiliser la classe `MulterError` qui est attachée à l'objet `multer` lui-même (e. . `err instanceof multer.MulterError`). +Multer errors carry a `code` (e.g. `LIMIT_FILE_SIZE`) and, when the error concerns +a specific field, its name in `field`. Errors about a specific file +(`LIMIT_FILE_SIZE`, `LIMIT_UNEXPECTED_FILE`) also expose the client-supplied file +name in `filename`; treat it as untrusted input, like `file.originalname`. + ```javascript const multer = require('multer'); const upload = multer().single('avatar'); @@ -368,5 +428,5 @@ Pour plus d'informations sur la façon de construire votre propre moteur de stoc [MIT](https://github.com/expressjs/multer/blob/HEAD/LICENSE) [npm-url]: https://npmjs.org/package/multer -[badge ossf-scorecard]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[visualiseur-scorecard-ossf]: 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/fr/resources/middleware/serve-favicon.mdx b/src/content/pages/fr/resources/middleware/serve-favicon.mdx index 66f6647090..01ec13f0cf 100644 --- a/src/content/pages/fr/resources/middleware/serve-favicon.mdx +++ b/src/content/pages/fr/resources/middleware/serve-favicon.mdx @@ -139,5 +139,5 @@ server.listen(3000); [downloads-url]: https://npmjs.org/package/serve-favicon [npm-url]: https://npmjs.org/package/serve-favicon -[badge ossf-scorecard]: https://api.scorecard.dev/projects/github.com/expressjs/serve-favicon/badge -[visualiseur-scorecard-ossf]: 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/fr/resources/middleware/serve-index.mdx b/src/content/pages/fr/resources/middleware/serve-index.mdx index 963371bb62..3bf283206b 100644 --- a/src/content/pages/fr/resources/middleware/serve-index.mdx +++ b/src/content/pages/fr/resources/middleware/serve-index.mdx @@ -52,7 +52,7 @@ Serve index accepte ces propriétés dans l'objet options. ##### Filtre -Appliquer cette fonction de filtre aux fichiers. `false` par défaut. The `filter` function +Appliquer cette fonction de filtre aux fichiers. Defaults to `false`. The `filter` function is called for each file, with the signature `filter(filename, index, files, dir)` where `filename` is the name of the file, `index` is the array index, `files` is the array of files and `dir` is the absolute path the file is located (and thus, @@ -60,11 +60,11 @@ the directory the listing is for). ##### hidden -Afficher les fichiers cachés (points). `false` par défaut. +Afficher les fichiers cachés (points). Defaults to `false`. ##### icônes -Afficher les icônes. `false` par défaut. +Afficher les icônes. Defaults to `false`. ##### stylesheet @@ -149,8 +149,8 @@ app.listen(3000); ## Licence -[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). Les icônes [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) -sont créées par/copyright de [FAMFAMFAM](https://web.archive.org/web/20251120154741/http://www.famfamfam.com/). +[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). The [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) icons +are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20230109095739/http://www.famfamfam.com/). [url appveyor]: https://ci.appveyor.com/project/dougwilson/serve-index [downloads-url]: https://npmjs.org/package/serve-index diff --git a/src/content/pages/fr/resources/middleware/session.mdx b/src/content/pages/fr/resources/middleware/session.mdx index 189688376b..8e0e6047d1 100644 --- a/src/content/pages/fr/resources/middleware/session.mdx +++ b/src/content/pages/fr/resources/middleware/session.mdx @@ -127,8 +127,8 @@ défini dans l'objet est ce qui est utilisé. ##### Partitionné -Spécifie la valeur `boolean` pour l'attribut [`Partitioned` `Set-Cookie`](https://github.com/expressjs/session/blob/HEAD/rfc-cutler-httpbis-partitioned-cookies) -. Quand vrai, l'attribut `Partitioned` est défini, sinon ce n'est pas le cas. +Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`][rfc-cutler-httpbis-partitioned-cookies] +attribute. Quand vrai, l'attribut `Partitioned` est défini, sinon ce n'est pas le cas. Par défaut, l'attribut `Partitioned` n'est pas défini. **Note** This is an attribute that has not yet been fully standardized, and may @@ -142,6 +142,12 @@ Plus d'informations à propos de la proposition peuvent être trouvées dans [la Spécifie la valeur pour le `Path` `Set-Cookie`. Par défaut, cette valeur est définie à `'/'`, qui est le chemin racine du domaine. +Since 1.19.1, path matching follows [RFC 6265 section 5.1.4][rfc-6265-5.1.4]. This means +the session middleware will only activate when the request path is an exact match or falls +under a segment boundary of the cookie path. For example, a cookie path of `/admin` will +match `/admin` and `/admin/users` but will **not** match `/administrator`. Prior versions +used a simple prefix check that did not enforce segment boundaries. + ##### Priorité du cookie Spécifie la `string` pour être la valeur de l'attribut [`Priority` `Set-Cookie`[rfc-west-cookie-priority-00-4.1]. @@ -1001,6 +1007,7 @@ Sous Windows, utilisez la commande correspondante ; [MIT](https://github.com/expressjs/session/blob/HEAD/LICENSE) +[rfc-6265-5.1.4]: https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 [rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.2.7 [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 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 6df5cf25e9..325265d003 100644 --- a/src/content/pages/it/advanced/best-practice-security.mdx +++ b/src/content/pages/it/advanced/best-practice-security.mdx @@ -48,7 +48,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) { @@ -269,7 +269,7 @@ $ npm audit Se vuoi rimanere più sicuro, considera [Snyk](https://snyk.io/). -Snyk offre sia un [strumento da riga di comando](https://www.npmjs.com/package/snyk) che una [integrazione Github](https://snyk.io/docs/github) che controlla la tua applicazione contro [database di vulnerabilità open source di Snyk](https://snyk.io/vuln/) per qualsiasi vulnerabilità nota nelle tue dipendenze. Installare il CLI come segue: +Snyk offre sia un [strumento da riga di comando](https://www.npmjs.com/package/snyk) che una [integrazione Github](https://docs.snyk.io/discover-snyk/getting-started) che controlla la tua applicazione contro [database di vulnerabilità open source di Snyk](https://security.snyk.io/) per qualsiasi vulnerabilità nota nelle tue dipendenze. Installare il CLI come segue: ```bash $ npm install -g snyk @@ -286,7 +286,7 @@ $ snyk test Keep an eye out for [GitHub Advisory Database](https://github.com/advisories?query=ecosystem%3Anpm) or [Snyk](https://security.snyk.io/vuln/npm) advisories that may affect Express or other modules that your app uses. In generale, queste banche dati sono risorse eccellenti per la conoscenza e gli strumenti sulla sicurezza del nodo. -Infine, Express apps—come qualsiasi altra web app—può essere vulnerabile a una varietà di attacchi basati sul web. Conoscere se stessi con conosciute [vulnerabilità web](https://www.owasp.org/www-project-top-ten/) e prendere precauzioni per evitarli. +Infine, Express apps—come qualsiasi altra web app—può essere vulnerabile a una varietà di attacchi basati sul web. Conoscere se stessi con conosciute [vulnerabilità web](https://owasp.org/www-project-top-ten/) e prendere precauzioni per evitarli. ## Considerazioni aggiuntive @@ -296,6 +296,6 @@ Ecco alcuni ulteriori consigli dall'eccellente [Node.js Security Checklist](http - Difendi gli attacchi di SQL injection utilizzando query parametrizzate o dichiarazioni preparate. - Usa lo strumento open-source [sqlmap](http://sqlmap.org/) per rilevare le vulnerabilità di SQL injection nella tua app. - Usa gli strumenti [nmap](https://nmap.org/) e [sslyze](https://github.com/nabla-c0d3/sslyze) per testare la configurazione dei tuoi cifrari SSL, chiavi, rinegoziazione e validità del certificato. -- Usa [safe-regex](https://www.npmjs.com/package/safe-regex) per garantire che le tue espressioni regolari non siano suscettibili di [espressione regolare negazione del servizio](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) attacchi. +- Usa [safe-regex](https://www.npmjs.com/package/safe-regex) per garantire che le tue espressioni regolari non siano suscettibili di [espressione regolare negazione del servizio](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) attacchi. -[helmet]: https://helmetjs.github.io/ +[helmet]: https://helmet.js.org/ 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/guide/migrating-4.mdx b/src/content/pages/it/guide/migrating-4.mdx index 47e1fab229..70ad35ad92 100644 --- a/src/content/pages/it/guide/migrating-4.mdx +++ b/src/content/pages/it/guide/migrating-4.mdx @@ -43,133 +43,23 @@ che è necessario per eseguire l'app. Basta seguire questi passaggi: La seguente tabella elenca il middleware Express 3 e le loro controparti in Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Express 3Express 4
- express.bodyParser - - body-parser + - multer -
- express.compress - - Compressione -
- express.cookieSession - - cookie-session -
- express.cookieParser - - cookie-parser -
- express.logger - - morgan -
- express.session - - express-session -
- express.favicon - - serve-favicon -
- express.responseTime - - tempo di risposta -
- express.errorHandler - - errorhandler -
- express.methodOverride - - method-override -
- express.timeout - - connect-timeout -
- express.vhost - - vhost -
- express.csrf - - csurf -
- express.directory - - serve-index -
- express.static - - servo-statico -
+| Express 3 | Express 4 | +| ------------------------ | ------------------------------------------------------------------------------------------------------- | +| `express.bodyParser` | [body-parser](https://github.com/expressjs/body-parser) + [multer](https://github.com/expressjs/multer) | +| `express.compress` | [compression](https://github.com/expressjs/compression) | +| `express.cookieSession` | [cookie-session](https://github.com/expressjs/cookie-session) | +| `express.cookieParser` | [cookie-parser](https://github.com/expressjs/cookie-parser) | +| `express.logger` | [morgan](https://github.com/expressjs/morgan) | +| `express.session` | [express-session](https://github.com/expressjs/session) | +| `express.favicon` | [serve-favicon](https://github.com/expressjs/serve-favicon) | +| `express.responseTime` | [response-time](https://github.com/expressjs/response-time) | +| `express.errorHandler` | [errorhandler](https://github.com/expressjs/errorhandler) | +| `express.methodOverride` | [method-override](https://github.com/expressjs/method-override) | +| `express.timeout` | [connect-timeout](https://github.com/expressjs/timeout) | +| `express.vhost` | [vhost](https://github.com/expressjs/vhost) | +| `express.csrf` | [csurf](https://github.com/expressjs/csurf) | +| `express.directory` | [serve-index](https://github.com/expressjs/serve-index) | +| `express.static` | [serve-static](https://github.com/expressjs/serve-static) | Ecco la [lista completa](https://github.com/senchalabs/connect#middleware) di Express 4 middleware. @@ -305,78 +195,21 @@ che è specifico per il percorso. La seguente tabella elenca altre modifiche di piccole dimensioni ma importanti in Express 4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OggettoDescrizione
Node.jsExpress 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x.
`http.createServer()` - Il modulo `http` non è più necessario, a meno che non sia necessario lavorare direttamente con - esso (socket.io/SPDY/HTTPS). L'app può essere avviata utilizzando la funzione `app.listen()`. -
`app.configure()` - La funzione `app.configure()` è stata rimossa. Usa la funzione `process.env.NODE_ENV` o - `app.get('env')` per rilevare l'ambiente e configurare l'app di conseguenza. -
`json spaces` - The `json spaces` application property is disabled by default in Express 4. -
`req.accepted()` - Usa `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, and - `req.acceptsLanguages()`. -
`res.location()`Non risolve più gli URL relativi.
`req.params`È stato un array; ora un oggetto.
`res.locals`Era una funzione; ora un oggetto.
`res.headerSent`Cambiato in `res.headersSent`.
`app.route`Ora disponibile come `app.mountpath`.
`res.on('header')`rimosso.
`res.charset`rimosso.
`res.setHeader('Set-Cookie', val)` - La funzionalità è ora limitata all'impostazione del valore di base dei cookie. Usa - `res.cookie()` per le funzionalità aggiunte. -
+| Object | Descrizione | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Node.js | Express 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x. | +| `http.createServer()` | The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). L'app può essere avviata utilizzando la funzione `app.listen()`. | +| `app.configure()` | La funzione `app.configure()` è stata rimossa. Usa la funzione `process.env.NODE_ENV` o `app.get('env')` per rilevare l'ambiente e configurare l'app di conseguenza. | +| `json spaces` | The `json spaces` application property is disabled by default in Express 4. | +| `req.accepted()` | Usa `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, and `req.acceptsLanguages()`. | +| `res.location()` | No longer resolves relative URLs. | +| `req.params` | Was an array; now an object. | +| `res.locals` | Was a function; now an object. | +| `res.headerSent` | Changed to `res.headersSent`. | +| `app.route` | Now available as `app.mountpath`. | +| `res.on('header')` | Removed. | +| `res.charset` | Removed. | +| `res.setHeader('Set-Cookie', val)` | La funzionalità è ora limitata all'impostazione del valore di base dei cookie. Use `res.cookie()` for added functionality. | ## Migrazione ad esempio app diff --git a/src/content/pages/it/resources/middleware/body-parser.mdx b/src/content/pages/it/resources/middleware/body-parser.mdx index ab5d587d5f..273691de22 100644 --- a/src/content/pages/it/resources/middleware/body-parser.mdx +++ b/src/content/pages/it/resources/middleware/body-parser.mdx @@ -44,6 +44,10 @@ Questo modulo fornisce i seguenti parser: - [Analizzatore corpo testo](#bodyparsertextoptions) - [analizzatore di forma codificata URL](#bodyparserurlencodedoptions) +All parsers support automatic inflation of `gzip`, `br` (brotli), `deflate` +and `zstd` encodings. `zstd` is available in Node.js `^22.15.0` and +`>=23.8.0`. + Altri analizzatori del corpo che potrebbero interessarti: - [body](https://www.npmjs.com/package/body#readme) @@ -84,9 +88,8 @@ I vari errori restituiti da questo modulo sono descritti nella sezione ### bodyParser.json([options]) Restituisce middleware che analizza solo `json` e guarda solo le richieste dove -l'intestazione `Content-Type` corrisponde all'opzione `type`. Questo analizzatore accetta qualsiasi codifica -Unicode del corpo e supporta l'inflazione automatica delle codifiche `gzip`, -`br` (brotli) e `deflate`. +l'intestazione `Content-Type` corrisponde all'opzione `type`. This parser accepts any +Unicode encoding of the body. Un nuovo oggetto `body` contenente i dati analizzati viene compilato sull'oggetto `request` dopo il middleware (es. `req.body`). @@ -146,9 +149,7 @@ della richiesta. L'analisi può essere interrotta lanciando un errore. ### bodyParser.raw([options]) Restituisce il middleware che analizza tutti i corpi come `Buffer` e guarda solo le richieste -dove l'intestazione `Content-Type` corrisponde all'opzione `type`. Questo analizzatore -supporta l'inflazione automatica delle codifiche `gzip`, `br` (brotli) e `deflate` -. +dove l'intestazione `Content-Type` corrisponde all'opzione `type`. Un nuovo oggetto `body` contenente i dati analizzati viene compilato sull'oggetto `request` dopo il middleware (es. `req.body`). Questo sarà un oggetto `Buffer` @@ -194,23 +195,21 @@ della richiesta. L'analisi può essere interrotta lanciando un errore. ### bodyParser.text([options]) Restituisce middleware che analizza tutti i corpi come una stringa e guarda solo le richieste -dove l'intestazione `Content-Type` corrisponde all'opzione `type`. Questo analizzatore -supporta l'inflazione automatica delle codifiche `gzip`, `br` (brotli) e `deflate` -. +dove l'intestazione `Content-Type` corrisponde all'opzione `type`. -Una nuova stringa `body` contenente i dati analizzati è popolata sull'oggetto `request` -dopo il middleware (es. `req.body`). Questa sarà una stringa del corpo -. +A new `body` string containing the parsed data is populated on the `request` +object after the middleware (i.e. `req.body`). This will be a string of the +body. #### Opzioni -La funzione `text` richiede un oggetto `options` opzionale che può contenere una qualsiasi di -le seguenti chiavi: +The `text` function takes an optional `options` object that may contain any of +the following keys: ##### defaultCharset -Specifica il carattere predefinito impostato per il contenuto del testo se il set di caratteri non è -specificato nell'intestazione `Content-Type` della richiesta. Il valore predefinito è `utf-8`. +Specify the default character set for the text content if the charset is not +specified in the `Content-Type` header of the request. Il valore predefinito è `utf-8`. ##### gonfiare @@ -229,13 +228,13 @@ specifica il numero di byte; se si tratta di una stringa, il valore viene passat ##### tipo L'opzione `type` è usata per determinare quale tipo di media il middleware analizzerà -. Questa opzione può essere una stringa, un array di stringhe o una funzione. Se non -una funzione, L'opzione `type` è passata direttamente alla libreria -[type-is](https://www.npmjs.com/package/type-is#readme) e questa può -essere un nome di estensione (come `txt`), un tipo mime (come `text/plain`), o un tipo mime -con un carattere jolly (come `*/*` o `text/*`). Se una funzione, l'opzione `type` -è chiamata `fn(req)` e la richiesta viene analizzata se restituisce un valore vero -. Il valore predefinito è `text/plain`. +. Questa opzione può essere una stringa, un array di stringhe o una funzione. If not +a function, `type` option is passed directly to the +[type-is](https://www.npmjs.com/package/type-is#readme) library and this can +be an extension name (like `txt`), a mime type (like `text/plain`), or a mime +type with a wildcard (like `*/*` or `text/*`). If a function, the `type` +option is called as `fn(req)` and the request is parsed if it returns a +truthy value. Defaults to `text/plain`. ##### verifica @@ -245,29 +244,28 @@ della richiesta. L'analisi può essere interrotta lanciando un errore. ### bodyParser.urlencoded([options]) -Restituisce middleware che analizza solo i corpi `urlencoded` e guarda solo le richieste -dove l'intestazione `Content-Type` corrisponde all'opzione `type`. Questo analizzatore -accetta solo codifiche UTF-8 e ISO-8859-1 del corpo e supporta l'inflazione automatica -di codifiche `gzip`, `br` (brotli) e `deflate`. +Returns middleware that only parses `urlencoded` bodies and only looks at +requests where the `Content-Type` header matches the `type` option. This +parser accepts only UTF-8 and ISO-8859-1 encodings of the body. Un nuovo oggetto `body` contenente i dati analizzati viene compilato sull'oggetto `request` -dopo il middleware (es. `req.body`). Questo oggetto conterrà coppie chiave-valore -, dove il valore può essere una stringa o un array (quando `extended` è -`false`), o qualsiasi tipo (quando `extended` è `true`). +dopo il middleware (es. `req.body`). This object will contain +key-value pairs, where the value can be a string or array (when `extended` is +`false`), or any type (when `extended` is `true`). #### Opzioni -La funzione `urlencoded` richiede un oggetto `options` opzionale che può contenere -una delle seguenti chiavi: +The `urlencoded` function takes an optional `options` object that may contain +any of the following keys: -##### esteso +##### extended -La sintassi "estesa" consente di codificare oggetti e array ricchi nel formato codificato URL -, consentendo un'esperienza simile a JSON con codifica URL. Per ulteriori informazioni su -, si prega di vedere la libreria qs -. +The "extended" syntax allows for rich objects and arrays to be encoded into the +URL-encoded format, allowing for a JSON-like experience with URL-encoded. For +more information, please see the qs +library. -Il valore predefinito è `false`. +Defaults to `false`. ##### gonfiare @@ -285,21 +283,21 @@ specifica il numero di byte; se si tratta di una stringa, il valore viene passat ##### parameterLimit -L'opzione `parameterLimit` controlla il numero massimo di parametri che -sono ammessi nei dati codificati con URL. Se una richiesta contiene più parametri -di questo valore, un 413 sarà restituito al client. Predefinito a `1000`. +The `parameterLimit` option controls the maximum number of parameters that +are allowed in the URL-encoded data. If a request contains more parameters +than this value, a 413 will be returned to the client. Defaults to `1000`. ##### tipo L'opzione `type` è usata per determinare quale tipo di media il middleware analizzerà -. Questa opzione può essere una stringa, un array di stringhe o una funzione. Se non -una funzione, L'opzione `type` è passata direttamente alla libreria -[type-is](https://www.npmjs.com/package/type-is#readme) e questo può -essere un nome di estensione (come `urlencoded`), un tipo mime (come -`application/x-www-form-urlencoded`), o un tipo mime con un carattere jolly (come -`*/x-www-form-urlencoded`). Se una funzione, l'opzione `type` è chiamata come -`fn(req)` e la richiesta viene analizzata se restituisce un valore vero. Il valore predefinito -è `application/x-www-form-urlencoded`. +. Questa opzione può essere una stringa, un array di stringhe o una funzione. If not +a function, `type` option is passed directly to the +[type-is](https://www.npmjs.com/package/type-is#readme) library and this can +be an extension name (like `urlencoded`), a mime type (like +`application/x-www-form-urlencoded`), or a mime type with a wildcard (like +`*/x-www-form-urlencoded`). If a function, the `type` option is called as +`fn(req)` and the request is parsed if it returns a truthy value. Defaults +to `application/x-www-form-urlencoded`. ##### verifica @@ -309,131 +307,131 @@ della richiesta. L'analisi può essere interrotta lanciando un errore. ##### defaultCharset -Il set di caratteri predefinito da analizzare come, se non specificato nel tipo di contenuto. Deve essere -o `utf-8` o `iso-8859-1`. Il valore predefinito è `utf-8`. +The default charset to parse as, if not specified in content-type. Must be +either `utf-8` or `iso-8859-1`. Il valore predefinito è `utf-8`. ##### charsetSentinel -Indica se lasciare che il valore del parametro `utf8` abbia la precedenza come selettore charset -. Richiede che il modulo contenga un parametro chiamato `utf8` con un valore -di `\ `. Il valore predefinito è `false`. +Whether to let the value of the `utf8` parameter take precedence as the charset +selector. It requires the form to contain a parameter named `utf8` with a value +of `✓`. Defaults to `false`. ##### interpretNumericEntities -Indica se decodificare entità numeriche come `☺` quando analizzano un modulo iso-8859-1 -. Il valore predefinito è `false`. +Whether to decode numeric entities such as `☺` when parsing an iso-8859-1 +form. Defaults to `false`. -##### profondità +##### depth -L'opzione `depth` è usata per configurare la profondità massima della libreria `qs` quando `extended` è `true`. Questo consente di limitare la quantità di chiavi che vengono analizzate e può essere utile per prevenire certi tipi di abusi. Predefinito a `32`. Si raccomanda di mantenere questo valore il più basso possibile. +The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible. -## Errori +## Errors -I middlewares forniti da questo modulo creano errori utilizzando il modulo -[`http-errors`](https://www.npmjs.com/package/http-errors). Gli errori -avranno tipicamente una proprietà `status`/`statusCode` che contiene il codice di risposta HTTP -suggerito, una proprietà `expose` per determinare se la proprietà `message` -debba essere visualizzata al client, una proprietà `type` per determinare il tipo di errore -senza corrispondere con il `message`, e una proprietà `body` contenente -il corpo di lettura, se disponibile. +The middlewares provided by this module create errors using the +[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors +will typically have a `status`/`statusCode` property that contains the suggested +HTTP response code, an `expose` property to determine if the `message` property +should be displayed to the client, a `type` property to determine the type of +error without matching against the `message`, and a `body` property containing +the read body, if available. -Di seguito sono riportati gli errori comuni creati, anche se qualsiasi errore può venire attraverso -per vari motivi. +The following are the common errors created, though any error can come through +for various reasons. -### codifica del contenuto non supportata +### content encoding unsupported -Questo errore si verificherà quando la richiesta aveva un'intestazione `Content-Encoding` che -conteneva una codifica, ma l'opzione "inflation" era impostata a `false`. La proprietà -`status` è impostata su `415`, la proprietà `type` è impostata su -`'encoding. nsupported'`, e la proprietà `charset` sarà impostata sulla codifica -non supportata. +This error will occur when the request had a `Content-Encoding` header that +contained an encoding but the "inflation" option was set to `false`. The +`status` property is set to `415`, the `type` property is set to +`'encoding.unsupported'`, and the `charset` property will be set to the +encoding that is unsupported. -### analisi dell'entità non riuscita +### entity parse failed -Questo errore si verifica quando la richiesta conteneva un'entità che non poteva essere analizzata da -dal middleware. La proprietà `status` è impostata su `400`, la proprietà `type` -è impostata su `'entity.parse. ailed'`, e la proprietà `body` è impostata su -il valore dell'entità che non ha funzionato. +This error will occur when the request contained an entity that could not be +parsed by the middleware. The `status` property is set to `400`, the `type` +property is set to `'entity.parse.failed'`, and the `body` property is set to +the entity value that failed parsing. -### verifica entità non riuscita +### entity verify failed -Questo errore si verificherà quando la richiesta conteneva un'entità che non poteva essere la verifica -fallita dall'opzione `verifica` definita. La proprietà `status` è -impostata su `403`, la proprietà `type` è impostata su `'entity.verify. ailed'`, e la proprietà -`body` è impostata al valore dell'entità che ha fallito la verifica. +This error will occur when the request contained an entity that could not be +verified by the defined `verify` option. The `status` property is +set to `403`, the `type` property is set to `'entity.verify.failed'`, and the +`body` property is set to the entity value that failed verification. -### richiesta interrotta +### request aborted -Questo errore si verificherà quando la richiesta viene interrotta dal client prima di leggere -il corpo è finito. La proprietà `received` sarà impostata al numero di byte -ricevuti prima che la richiesta sia stata annullata e la proprietà `expected` sia -impostata al numero di byte previsti. La proprietà `status` è impostata su `400` -e la proprietà `type` è impostata su `'request.aborted'`. +This error will occur when the request is aborted by the client before reading +the body has finished. The `received` property will be set to the number of +bytes received before the request was aborted and the `expected` property is +set to the number of expected bytes. The `status` property is set to `400` +and `type` property is set to `'request.aborted'`. -### richiesta entità troppo grande +### request entity too large -Questo errore si verificherà quando la dimensione del corpo della richiesta è più grande dell'opzione "limite" -. La proprietà `limit` sarà impostata al limite del byte e la proprietà `length` -sarà impostata alla lunghezza del corpo della richiesta. La proprietà `status` è -impostata su `413` e la proprietà `type` è impostata su `'entity.too.large'`. +This error will occur when the request body's size is larger than the "limit" +option. The `limit` property will be set to the byte limit and the `length` +property will be set to the request body's length. The `status` property is +set to `413` and the `type` property is set to `'entity.too.large'`. -### la dimensione della richiesta non corrisponde alla lunghezza del contenuto +### request size did not match content length -Questo errore si verificherà quando la lunghezza della richiesta non corrisponde alla lunghezza da -l'intestazione `Content-Length`. Questo accade tipicamente quando la richiesta è malformata, -tipicamente quando l'intestazione `Content-Length` è stata calcolata in base ai caratteri -invece dei byte. La proprietà `status` è impostata su `400` e la proprietà `type` -è impostata su `'request.size.invalid'`. +This error will occur when the request's length did not match the length from +the `Content-Length` header. This typically occurs when the request is malformed, +typically when the `Content-Length` header was calculated based on characters +instead of bytes. The `status` property is set to `400` and the `type` property +is set to `'request.size.invalid'`. -### la codifica dello stream non deve essere impostata +### stream encoding should not be set -Questo errore si verificherà quando qualcosa chiamato il metodo `req.setEncoding` prima di -a questo middleware. Questo modulo opera direttamente solo su byte e non puoi chiamare -`req.setEncoding` quando usi questo modulo. La proprietà `status` è impostata su -`500` e la proprietà `type` è impostata su `'stream.encoding.set'`. +This error will occur when something called the `req.setEncoding` method prior +to this middleware. This module operates directly on bytes only and you cannot +call `req.setEncoding` when using this module. The `status` property is set to +`500` and the `type` property is set to `'stream.encoding.set'`. -### lo stream non è leggibile +### stream is not readable -Questo errore si verificherà quando la richiesta non è più leggibile quando questo middleware -tenta di leggerla. Questo in genere significa qualcosa di diverso da un middleware di -questo modulo legge già il corpo della richiesta e il middleware è stato anche configurato per -leggere la stessa richiesta. La proprietà `status` è impostata su `500` e la proprietà `type` -è impostata su `'stream.not.readable'`. +This error will occur when the request is no longer readable when this middleware +attempts to read it. This typically means something other than a middleware from +this module read the request body already and the middleware was also configured to +read the same request. The `status` property is set to `500` and the `type` +property is set to `'stream.not.readable'`. -### troppi parametri +### too many parameters -Questo errore si verificherà quando il contenuto della richiesta supera il file `parameterLimit` configurato -per l'analizzatore `urlencoded`. La proprietà `status` è impostata su -`413` e la proprietà `type` è impostata su `'parameters.too.mani'`. +This error will occur when the content of the request exceeds the configured +`parameterLimit` for the `urlencoded` parser. The `status` property is set to +`413` and the `type` property is set to `'parameters.too.many'`. -### charset "BOGUS" non supportato +### unsupported charset "BOGUS" -Questo errore si verificherà quando la richiesta aveva un parametro charset nell'intestazione -`Content-Type`, ma il modulo `iconv-lite` non lo supporta OR l'analizzatore -non lo supporta. Il set di caratteri è contenuto anche nel messaggio -come nella proprietà `charset`. La proprietà `status` è impostata su `415`, la proprietà `type` -è impostata su `'charset. nsupported'`, e la proprietà `charset` -è impostata al set di caratteri non supportato. +This error will occur when the request had a charset parameter in the +`Content-Type` header, but the `iconv-lite` module does not support it OR the +parser does not support it. The charset is contained in the message as well +as in the `charset` property. The `status` property is set to `415`, the +`type` property is set to `'charset.unsupported'`, and the `charset` property +is set to the charset that is unsupported. -### codifica dei contenuti "bogus" non supportata +### unsupported content encoding "bogus" -Questo errore si verificherà quando la richiesta aveva un'intestazione `Content-Encoding` che -conteneva una codifica non supportata. La codifica è contenuta nel messaggio -e nella proprietà `encoding`. La proprietà `status` è impostata su `415`, -la proprietà `type` è impostata su `'encoding. nsupported'`, e la proprietà `encoding` -è impostata sulla codifica non supportata. +This error will occur when the request had a `Content-Encoding` header that +contained an unsupported encoding. The encoding is contained in the message +as well as in the `encoding` property. The `status` property is set to `415`, +the `type` property is set to `'encoding.unsupported'`, and the `encoding` +property is set to the encoding that is unsupported. -### L'ingresso ha superato la profondità +### The input exceeded the depth -Questo errore si verifica quando si utilizza `bodyParser.urlencoded` con la proprietà `extended` impostata su `true` e l'input supera l'opzione `depth` configurata. La proprietà `status` è impostata su `400`. Si consiglia di rivedere l'opzione `depth` e valutare se richiede un valore superiore. Quando l'opzione `depth` è impostata a `32` (valore predefinito), l'errore non verrà lanciato. +This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown. ## Esempi ### Express/Connect top-level generic -Questo esempio dimostra l'aggiunta di un parser generico codificato da JSON e URL come middleware di primo livello -, che analizzerà i corpi di tutte le richieste in arrivo. -Questa è la configurazione più semplice. +This example demonstrates adding a generic JSON and URL-encoded parser as a +top-level middleware, which will parse the bodies of all incoming requests. +This is the simplest setup. ```js const express = require('express'); @@ -454,10 +452,10 @@ app.use(function (req, res) { }); ``` -### Percorso espresso specifico +### Express route-specific -Questo esempio dimostra l'aggiunta di body parsers specificamente alle rotte che -ne hanno bisogno. In generale, questo è il modo più consigliato per utilizzare body parser con +This example demonstrates adding body parsers specifically to the routes that +need them. In general, this is the most recommended way to use body-parser with Express. ```js @@ -485,10 +483,10 @@ app.post('/api/users', jsonParser, function (req, res) { }); ``` -### Modifica il tipo accettato per gli analizzatori +### Change accepted type for parsers -Tutti i parser accettano un'opzione `type` che ti permette di modificare il file `Content-Type` di -che il middleware analizzerà. +All the parsers accept a `type` option which allows you to change the +`Content-Type` that the middleware will parse. ```js const express = require('express'); diff --git a/src/content/pages/it/resources/middleware/compression.mdx b/src/content/pages/it/resources/middleware/compression.mdx index 6cece826f3..5e1546ab3a 100644 --- a/src/content/pages/it/resources/middleware/compression.mdx +++ b/src/content/pages/it/resources/middleware/compression.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -21,13 +21,13 @@ Sono supportati i seguenti codici di compressione: - gzip - br (brotli) -**Nota** Brotli è supportato solo dalle versioni v11.7.0 e v10.16.0 di Node.js. +**Note** Brotli is available in all currently supported Node.js LTS versions (v18+). ## Installa Questo è un modulo [Node.js](https://nodejs.org/en/) disponibile attraverso la [npm registry](https://www.npmjs.com/). L'installazione viene eseguita usando il comando -[`npm install`](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): +[`npm install`](https://docs.npmjs.com/downloading-and-installing-packages-locally): @@ -304,7 +304,7 @@ Il progetto Express.js accoglie con favore tutti i contributi costruttivi. I con dal codice per correzioni di bug e miglioramenti, alle aggiunte e correzioni alla documentazione, test aggiuntivi, richieste di pull in entrata di prova e problemi, e altro ancora! -Vedi la [Guida al contributo](https://github.com/expressjs/express/blob/master/Contributing.md) per maggiori dettagli tecnici sul contributo. +See the [Contributing Guide](https://github.com/expressjs/.github/blob/HEAD/CONTRIBUTING.md) for more technical details on contributing. ## Licenza diff --git a/src/content/pages/it/resources/middleware/morgan.mdx b/src/content/pages/it/resources/middleware/morgan.mdx index 6b7d5da22e..195d1eaa16 100644 --- a/src/content/pages/it/resources/middleware/morgan.mdx +++ b/src/content/pages/it/resources/middleware/morgan.mdx @@ -8,14 +8,14 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; Richiesta HTTP middleware logger per node.js -> Chiamato dopo [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), uno spettacolo che non si dovrebbe guardare fino al completamento. +> Named after [Dexter](https://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. ## Installazione @@ -35,6 +35,16 @@ Questo è un modulo [Node.js](https://nodejs.org/en/) disponibile attraverso la ## API +For ES Modules: + +{/* eslint-disable no-unused-vars */} + +```js +import morgan from 'morgan'; +``` + +For CommonJS: + {/* eslint-disable no-unused-vars */} ```js @@ -78,10 +88,12 @@ morgan(function (tokens, req, res) { tokens.method(req, res), tokens.url(req, res), tokens.status(req, res), - tokens.res(req, res, 'content-length'), '-', - tokens['response-time'](https://github.com/expressjs/morgan/blob/HEAD/req, res), 'ms' - ].join(' ') -}) + tokens.res(req, res, 'content-length'), + '-', + tokens['response-time'](req, res), + 'ms', + ].join(' '); +}); ``` #### Opzioni @@ -90,9 +102,9 @@ Morgan accetta queste proprietà nell'oggetto opzioni. ##### immediato -Scrivi la riga di log su richiesta invece di rispondere. Ciò significa che le richieste -saranno registrate anche se il server si blocca _ma i dati della risposta (come il codice di risposta -, la lunghezza del contenuto, ecc.) non può essere registrato_. +Scrivi la riga di log su richiesta invece di rispondere. This means that requests will +be logged even if the server crashes, _but data from the response (like the +response code, content length, etc.) non può essere registrato_. ##### salta @@ -114,6 +126,33 @@ morgan('combined', { Flusso di uscita per la scrittura di linee di registro, predefinito per `process.stdout`. +If the stream is in object mode (`stream.writableObjectMode` is `true`) and the +format function returns an object, the object is written to the stream as-is, +without a trailing newline. This allows passing structured log entries to +loggers that accept objects: + +{/* eslint-disable no-undef */} + +```js +morgan( + function (tokens, req, res) { + return { + method: tokens.method(req, res), + url: tokens.url(req, res), + status: Number(tokens.status(req, res)), + }; + }, + { + stream: { + writableObjectMode: true, + write: function (entry) { + // entry is the object returned by the format function + }, + }, + } +); +``` + #### Formati Predefiniti Ci sono vari formati predefiniti forniti: @@ -151,6 +190,11 @@ non colorato per i codici di informazione. GET /dev 200 0.224 ms - 2 ``` +Coloring is disabled when the [`NO_COLOR`](https://no-color.org) environment +variable is set to any non-empty value, in which case the output above is +written without any escape sequences. The variable is read once, when `morgan` +is first required. + ##### breve Più breve del predefinito, compreso anche il tempo di risposta. @@ -191,8 +235,8 @@ Chiamando `morgan.token()` usando lo stesso nome di un token esistente sovrascri . La funzione token dovrebbe essere chiamata con gli argomenti `req` e `res`, che rappresentano -la richiesta HTTP e la risposta HTTP. Inoltre, il token può accettare ulteriori argomenti di -sta scegliendo di personalizzare il comportamento. +la richiesta HTTP e la risposta HTTP. Additionally, the token can accept further arguments of +its choosing to customize behavior. ##### :date[format] @@ -218,7 +262,7 @@ L'ID di processo del processo Node.js che gestisce la richiesta. ##### -L'intestazione Referrer della richiesta. Questo userà l'intestazione standard errata Referer se esiste, altrimenti Referrer. +L'intestazione Referrer della richiesta. This will use the standard mis-spelled Referer header if it exists, otherwise Referrer. ##### :remote-addr @@ -264,7 +308,7 @@ includere sul numero, default di `3`, che fornisce precisione microsecondo. ##### -L'URL della richiesta. Questo userà `req.originalUrl` se esiste, altrimenti `req.url`. +L'URL della richiesta. This will use `req.originalUrl` if it exists, otherwise `req.url`. ##### :user-agent @@ -274,13 +318,13 @@ Il contenuto dell'intestazione User-Agent della richiesta. Compila una stringa di formato in una funzione `format` per l'uso da parte di `morgan`. Una stringa di formato è una stringa che rappresenta una singola riga di registro e può utilizzare la sintassi token. -I token sono riferimenti da `:token-name`. Se i token accettano argomenti, possono +Tokens are referenced by `:token-name`. Se i token accettano argomenti, possono essere passati usando `[]`, per esempio: `:token-name[pretty]` passerebbe la stringa `'pretty'` come argomento al token `token-name`. -La funzione restituita da `morgan. ompile` richiede tre argomenti `tokens`, `req`, e -`res`, dove `tokens` è oggetto con tutti i token definiti, `req` è la richiesta HTTP e -`res` è la risposta HTTP. La funzione restituirà una stringa che sarà la riga di log, +The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and +`res`, where `tokens` is an object with all defined tokens, `req` is the HTTP request and +`res` is the HTTP response. La funzione restituirà una stringa che sarà la riga di log, o `undefined` / `null` per saltare la registrazione. Normalmente i formati sono definiti usando `morgan.format(name, format)`, ma per certi usi @@ -290,7 +334,7 @@ avanzati, questa funzione di compilazione è direttamente disponibile. ### express/connect -App di esempio che registrerà tutte le richieste nel formato combinato Apache a STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var express = require('express'); @@ -307,7 +351,7 @@ app.get('/', function (req, res) { ### server http vanilla -App di esempio che registrerà tutte le richieste nel formato combinato Apache a STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var finalhandler = require('finalhandler'); @@ -431,7 +475,7 @@ App di esempio che utilizzerà formati di token personalizzati. Questo aggiunge ```js var express = require('express'); var morgan = require('morgan'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); morgan.token('id', function getId(req) { return req.id; diff --git a/src/content/pages/it/resources/middleware/multer.mdx b/src/content/pages/it/resources/middleware/multer.mdx index b754686c97..366cd77c69 100644 --- a/src/content/pages/it/resources/middleware/multer.mdx +++ b/src/content/pages/it/resources/middleware/multer.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -18,23 +18,6 @@ in cima a [busboy](https://github.com/mscdex/busboy) per la massima efficienza. **NOTA**: Multer non elaborerà alcun modulo che non sia multipart (`multipart/form-data`). -## Traduzioni - -Questo README è disponibile anche in altre lingue: - -| | | -| ---------------------------------------------------------------------------------------- | --------------- | -| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabo | -| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Cinese | -| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | Francese | -| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Coreano | -| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portoghese (BR) | -| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russo | -| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spagnolo | -| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek | -| [Nome Vie\ \ ](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) | Turco | - ## Installazione @@ -130,23 +113,26 @@ app.post('/stats', upload.single('uploaded_file'), function (req, res) { }); ``` +Complete client-side and server-side examples (browser `FormData` uploads of a +blob and of an image) are in the [`examples/`](https://github.com/expressjs/multer/blob/HEAD/examples/) folder. + ## API ### Informazioni sul file Ogni file contiene le seguenti informazioni: -| Chiave | Descrizione | Nota | -| -------------- | ------------------------------------------------- | --------------- | -| `fieldname` | Nome del campo specificato nella forma | | -| `originalname` | Nome del file sul computer dell'utente | | -| `encoding` | Tipo di codifica del file | | -| `mimetype` | Tipo MIME del file | | -| `size` | Dimensione del file in byte | | -| `destinazione` | La cartella in cui il file è stato salvato | `DiskStorage` | -| `nomefile` | Il nome del file all'interno della `destinazione` | `DiskStorage` | -| `path` | Il percorso completo del file caricato | `DiskStorage` | -| `buffer` | Un `Buffer` dell'intero file | `MemoryStorage` | +| Chiave | Descrizione | Nota | +| -------------- | ----------------------------------------------------------------------------------- | --------------- | +| `fieldname` | Nome del campo specificato nella forma | | +| `originalname` | Name of the file on the user's computer, or the full path when `preservePath: true` | | +| `encoding` | Tipo di codifica del file | | +| `mimetype` | Tipo MIME del file | | +| `size` | Dimensione del file in byte | | +| `destinazione` | La cartella in cui il file è stato salvato | `DiskStorage` | +| `nomefile` | Il nome del file all'interno della `destinazione` | `DiskStorage` | +| `path` | Il percorso completo del file caricato | `DiskStorage` | +| `buffer` | Un `Buffer` dell'intero file | `MemoryStorage` | ### `multer(opts)` @@ -161,11 +147,15 @@ Di seguito sono riportate le opzioni che possono essere passate a Multer. | Chiave | Descrizione | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `defCharset` | Default character set to use for text field values that do not declare one. Default: `'utf8'` | +| `defParamCharset` | Set di caratteri predefinito da usare per i valori dei parametri dell'intestazione della parte (ad esempio nome file) che non sono parametri estesi (che contengono un set di caratteri esplicito). Predefinito: `'latin1'` | | `dest` o `storage` | Dove memorizzare i file | | `fileFilter` | Funzione per controllare quali file sono accettati | +| `fileHwm` | `highWaterMark` of each file stream (`file.stream`). Default: busboy's default | +| `highWaterMark` | `highWaterMark` of the multipart parser stream. Default: busboy's default | | `limits` | Limiti dei dati caricati | -| `preservePath` | Mantenere il percorso completo dei file invece del solo nome di base | -| `defParamCharset` | Set di caratteri predefinito da usare per i valori dei parametri dell'intestazione della parte (ad esempio nome file) che non sono parametri estesi (che contengono un set di caratteri esplicito). Predefinito: `'latin1'` | +| `preservePath` | Keep the full client-supplied path in `file.originalname` instead of just the base name | +| `streamHandler` | Function that feeds the request body to busboy; defaults to `req.pipe(busboy)` | In una media web app, potrebbe essere richiesto solo `dest`, e configurato come mostrato in il seguente esempio. @@ -174,6 +164,14 @@ il seguente esempio. const upload = multer({ dest: 'uploads/' }); ``` +When `preservePath` is enabled, Multer passes the incoming filename through with +any path segments provided by the client. This is exposed as `file.originalname`; +it does not change the destination folder, create directories, or sanitize the +path for you. `file.originalname` is always client-supplied and should be treated +as untrusted; with `preservePath` it additionally contains the path segments the +client sent. Normalize or validate it before using it in a custom `filename` or +storage engine. + Se vuoi più controllo sui tuoi upload, vuoi usare l'opzione `storage` invece di `dest`. Navi multiple con motori di stoccaggio `DiskStorage` e `MemoryStorage`; Più motori sono disponibili da terze parti. @@ -189,6 +187,9 @@ Accetta un array di file, tutti con il nome `fieldname`. Opzionalmente errore se più di file `maxCount` vengono caricati. L'array dei file sarà memorizzato in `req.files`. +Files skipped by `fileFilter` do not count towards `maxCount`. Use +`limits.files` to bound how many files are read from a request. + #### `.fields(fields)` Accetta un mix di file, specificato da `fields`. Un oggetto con array di file @@ -206,12 +207,12 @@ Esempio: #### `.none()` -Accetta solo campi di testo. Se viene effettuato un caricamento del file, verrà emesso un errore con il codice -"LIMIT_UNEXPECTED_FILE". +Accetta solo campi di testo. If any file upload is made, error with code +`LIMIT_UNEXPECTED_FILE` will be issued. #### `.any()` -Accetta tutti i file che vengono sopra il filo. Un array di file sarà memorizzato in +Accepts all files that come over the wire. Un array di file sarà memorizzato in `req.files`. **ATTENZIONE:** Assicurati di gestire sempre i file caricati da un utente. @@ -226,21 +227,26 @@ dove gestisci i file caricati. Il motore di archiviazione del disco ti dà pieno controllo sulla memorizzazione dei file su disco. ```javascript +const crypto = require('crypto'); + const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/tmp/my-uploads'); }, filename: function (req, file, cb) { - const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); - cb(null, file.fieldname + '-' + uniqueSuffix); + crypto.randomBytes(16, function (err, raw) { + if (err) return cb(err); + cb(null, file.fieldname + '-' + raw.toString('hex')); + }); }, }); const upload = multer({ storage: storage }); ``` -Ci sono due opzioni disponibili, `destinazione` e `nomefile`. Sono entrambe funzioni -che determinano dove il file deve essere memorizzato. +There are three options available: `destination`, `filename` and `flush`. All of +them except `flush` are functions that determine where the file should be +stored. `destination` è usato per determinare in quale cartella i file caricati dovrebbero essere memorizzati. Questo può anche essere dato come una `string` (ad esempio `'/tmp/uploads'`). If no @@ -268,6 +274,14 @@ Per capire la convenzione di chiamata utilizzata nel callback (necessità di pas null come primo parametro), fare riferimento a [Node. s gestione degli errori](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors) +`flush` is an optional boolean. When set to `true`, the file data is flushed to +disk with an `fsync` call before the upload handler runs, which prevents data +loss if the process or the system crashes while the data is still sitting in +the operating system's page cache. It is disabled by default because forcing a +disk flush on every upload has a performance cost. Note that this syncs the +file contents only; if the new directory entry must survive a crash as well, +fsync the destination directory yourself. + #### `MemoryStorage` Il motore di memorizzazione memoria memorizza i file in memoria come oggetti `Buffer`. non ha alcuna opzione. @@ -286,20 +300,36 @@ molto rapidamente, può causare che l'applicazione esaurisca la memoria quando v ### `limits` -Un oggetto che specifica i limiti di dimensione delle seguenti proprietà opzionali. Multer passa questo oggetto direttamente nel busboy, e i dettagli delle proprietà possono essere trovati su [busboy's page](https://github.com/mscdex/busboy#busboy-methods). +Un oggetto che specifica i limiti di dimensione delle seguenti proprietà opzionali. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#exports). + +`limits` can also be a function that receives the request and returns such an +object. It is called once per request, before parsing starts, so limits can +depend on e.g. the authenticated user: + +```javascript +const upload = multer({ + limits: function (req) { + return { fileSize: req.user.maxUploadSize }; + }, +}); +``` + +Limits apply to the whole request; there is no per-file limit. To restrict +individual files by type or name, use `fileFilter` or a custom storage engine. Sono disponibili i seguenti valori interi: -| Chiave | Descrizione | Predefinito | -| ------------------- | ------------------------------------------------------------------------------------------- | ----------- | -| `fieldNameSize` | Dimensione massima nome campo | 100 byte | -| `fieldSize` | Dimensione massima del campo (in byte) | 1MB | -| `fields` | Numero massimo di campi non file | Infinito | -| `fileSize` | Per forme multiple, la dimensione massima del file (in byte) | Infinito | -| `files` | Per forme multiple, il numero massimo di campi di file | Infinito | -| `parts` | Per forme multiple, il numero massimo di parti (campi + file) | Infinito | -| `headerPairs` | Per forme multiparti, il numero massimo di chiavi intestazione=>valore coppie da analizzare | 2000 | -| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinito | +| Chiave | Descrizione | Predefinito | +| ---------------------- | ------------------------------------------------------------------------------------------- | ----------- | +| `fieldNameSize` | Dimensione massima nome campo | Infinito | +| `fieldSize` | Dimensione massima del campo (in byte) | 1MB | +| `fields` | Numero massimo di campi non file | Infinito | +| `fileSize` | Per forme multiple, la dimensione massima del file (in byte) | Infinito | +| `files` | Per forme multiple, il numero massimo di campi di file | Infinito | +| `parts` | Per forme multiple, il numero massimo di parti (campi + file) | Infinito | +| `headerPairs` | Per forme multiparti, il numero massimo di chiavi intestazione=>valore coppie da analizzare | 2000 | +| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinito | +| `fieldArrayIndexLimit` | Max numeric array index accepted inside a field name (e.g. `a[3]` uses index 3) | Infinito | Specificare i limiti può aiutare a proteggere il vostro sito dagli attacchi di negazione del servizio (DoS). @@ -324,6 +354,30 @@ function fileFilter(req, file, cb) { } ``` +### `streamHandler` + +By default Multer reads the request with `req.pipe(busboy)`. Some platforms +consume the request body before your handlers run, so there is nothing left to +pipe. Google Cloud Functions and Firebase Functions, for example, expose the +already-read body as `req.rawBody`. Provide a `streamHandler` to feed busboy +yourself in that case: + +```javascript +const upload = multer({ + storage: multer.memoryStorage(), + streamHandler: function (req, busboy) { + if (req.rawBody) { + busboy.end(req.rawBody); + } else { + req.pipe(busboy); + } + }, +}); +``` + +The function receives the request and the busboy instance and must write the +whole multipart body to busboy and end it. + ## Security Specifying the [limits](#limits) can help protect your site against denial of service (DoS) attacks. The following limits are recommended for most applications: @@ -332,6 +386,7 @@ Specifying the [limits](#limits) can help protect your site against denial of se - `files` -- set to the maximum number of files per request - `fields` -- set to the maximum number of text fields per request - `fieldNestingDepth` -- set to the minimum depth your field names require (e.g. `3` for `a[b][c]`) +- `fieldArrayIndexLimit` -- set to the largest array index your field names require (e.g. `100` for `a[99]`) ## Gestione errori @@ -341,6 +396,11 @@ una bella pagina di errore usando [lo standard express way](/guide/error-handlin Se si desidera catturare errori specificamente da Multer, è possibile chiamare la funzione middleware da soli. Inoltre, se si desidera catturare solo [gli errori Multer](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), puoi usare la classe `MulterError` che è collegata all'oggetto `multer` stesso (e. . `err instanceof multer.MulterError`). +Multer errors carry a `code` (e.g. `LIMIT_FILE_SIZE`) and, when the error concerns +a specific field, its name in `field`. Errors about a specific file +(`LIMIT_FILE_SIZE`, `LIMIT_UNEXPECTED_FILE`) also expose the client-supplied file +name in `filename`; treat it as untrusted input, like `file.originalname`. + ```javascript const multer = require('multer'); const upload = multer().single('avatar'); diff --git a/src/content/pages/it/resources/middleware/serve-index.mdx b/src/content/pages/it/resources/middleware/serve-index.mdx index caa11797ed..5378fe3510 100644 --- a/src/content/pages/it/resources/middleware/serve-index.mdx +++ b/src/content/pages/it/resources/middleware/serve-index.mdx @@ -52,7 +52,7 @@ Serve index accetta queste proprietà nell'oggetto opzioni. ##### filtro -Applica questa funzione di filtro ai file. Il valore predefinito è `false`. La funzione `filter` +Applica questa funzione di filtro ai file. Defaults to `false`. La funzione `filter` è chiamata per ogni file, con la firma `filter(filename, index, files, dir)` dove `filename` è il nome del file, `index` è l'indice dell'array, `files` è l'array di file e `dir` è il percorso assoluto che il file si trova (e quindi, @@ -60,11 +60,11 @@ la directory per la quale è inserita). ##### hidden -Mostra file nascosti (dot). Il valore predefinito è `false`. +Mostra file nascosti (dot). Defaults to `false`. ##### icone -Visualizza le icone. Il valore predefinito è `false`. +Visualizza le icone. Defaults to `false`. ##### stylesheet @@ -149,8 +149,8 @@ app.listen(3000); ## Licenza -[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). Le icone [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) -sono create da/copyright di [FAMFAMFAM](https://web.archive.org/web/20251120154741/http://www.famfamfam.com/). +[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). The [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) icons +are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20230109095739/http://www.famfamfam.com/). [appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index [downloads-url]: https://npmjs.org/package/serve-index diff --git a/src/content/pages/it/resources/middleware/session.mdx b/src/content/pages/it/resources/middleware/session.mdx index 9cafcb714e..76b1fe36ff 100644 --- a/src/content/pages/it/resources/middleware/session.mdx +++ b/src/content/pages/it/resources/middleware/session.mdx @@ -127,8 +127,8 @@ definito nell'oggetto è quello che viene utilizzato. ##### cookie.partizionato -Specifica il valore `boolean` per l'attributo [`Partitioned` `Set-Cookie`](https://github.com/expressjs/session/blob/HEAD/rfc-cutler-httpbis-partitioned-cookies) -. Quando veritiero, l'attributo `Partitioned` è impostato, altrimenti non lo è. +Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`][rfc-cutler-httpbis-partitioned-cookies] +attribute. Quando veritiero, l'attributo `Partitioned` è impostato, altrimenti non lo è. Per impostazione predefinita, l'attributo `Partitioned` non è impostato. **Nota** Questo è un attributo che non è stato ancora completamente standardizzato e che potrebbe cambiare in futuro. Questo significa anche che molti clienti possono ignorare questo attributo fino a quando non lo capiscono. @@ -140,6 +140,12 @@ Per maggiori informazioni su [la proposta](https://github.com/privacycg/CHIPS). Specifica il valore per il `Path` `Set-Cookie`. Per impostazione predefinita, questo è impostato a `'/'`, quale è il percorso principale del dominio. +Since 1.19.1, path matching follows [RFC 6265 section 5.1.4][rfc-6265-5.1.4]. This means +the session middleware will only activate when the request path is an exact match or falls +under a segment boundary of the cookie path. For example, a cookie path of `/admin` will +match `/admin` and `/admin/users` but will **not** match `/administrator`. Prior versions +used a simple prefix check that did not enforce segment boundaries. + ##### cookie.priority Specifica che la `string` sia il valore per l'attributo `Set-Cookie`][rfc-west-cookie-priority-00-4.1]. @@ -1002,6 +1008,7 @@ Su Windows, utilizzare il comando corrispondente; [MIT](https://github.com/expressjs/session/blob/HEAD/LICENSE) +[rfc-6265-5.1.4]: https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 [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-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 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 f5d9e2db58..fc0700e846 100644 --- a/src/content/pages/ja/advanced/best-practice-security.mdx +++ b/src/content/pages/ja/advanced/best-practice-security.mdx @@ -6,9 +6,9 @@ description: 運用中のExpressアプリのセキュリティベストプラク import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -_"production"_ という用語は、アプリケーションや API がエンドユーザーや消費者に一般的に提供されるソフトウェアのライフサイクルにおける段階を指します。 対照的に、\*"development"\*段階では、コードを積極的に書いたりテストしたりしており、アプリケーションは外部からのアクセスに開かれていません。 対応するシステム環境はそれぞれ _production_ と _development_ と呼ばれています。 対照的に、*"development"*段階では、コードを積極的に書いたりテストしたりしており、アプリケーションは外部からのアクセスに開かれていません。 対応するシステム環境はそれぞれ _production_ と _development_ と呼ばれています。 +_"production"_ という用語は、アプリケーションや API がエンドユーザーや消費者に一般的に提供されるソフトウェアのライフサイクルにおける段階を指します。 対照的に、\*"development"\*段階では、コードを積極的に書いたりテストしたりしており、アプリケーションは外部からのアクセスに開かれていません。 対応するシステム環境はそれぞれ _production_ と _development_ と呼ばれています。対照的に、*"development"*段階では、コードを積極的に書いたりテストしたりしており、アプリケーションは外部からのアクセスに開かれていません。対応するシステム環境はそれぞれ _production_ と _development_ と呼ばれています。 -開発環境と生産環境は通常、異なる設定であり、非常に異なる要件を持っています。 開発で問題のあるものは、生産では受け入れられないかもしれません。 たとえば、開発環境では、デバッグ用のエラーの詳細なロギングを行うことができます。 同じ行動が本番環境ではセキュリティ上の懸念になることがあります 開発では拡張性、信頼性、パフォーマンスを心配する必要はありませんが、それらの懸念は生産において重要になります。 +開発環境と生産環境は通常、異なる設定であり、非常に異なる要件を持っています。開発で問題のあるものは、生産では受け入れられないかもしれません。たとえば、開発環境では、デバッグ用のエラーの詳細なロギングを行うことができます。 同じ行動が本番環境ではセキュリティ上の懸念になることがあります開発では拡張性、信頼性、パフォーマンスを心配する必要はありませんが、それらの懸念は生産において重要になります。 @@ -19,23 +19,22 @@ Express でセキュリティ上の脆弱性を発見したと思われる場合 ## 非推奨または脆弱なバージョンの Express を使用しない -Express 2.x と 3.x はメンテナンスされなくなりました。 これらのバージョンのセキュリティとパフォーマンスの問題は修正されません。 それらを使用しないでください! これらのバージョンのセキュリティとパフォーマンスの問題は修正されません。 それらを使用しないでください! If you haven't moved to version 4, follow the [migration guide](/guide/migrating-4) or consider [Commercial Support Options](/support#commercial-support-options). +Express 2.x と 3.x はメンテナンスされなくなりました。 これらのバージョンのセキュリティとパフォーマンスの問題は修正されません。 それらを使用しないでください! これらのバージョンのセキュリティとパフォーマンスの問題は修正されません。それらを使用しないでください! If you haven't moved to version 4, follow the [migration guide](/guide/migrating-4) or consider [Commercial Support Options](/support#commercial-support-options). Also ensure you are not using any of the vulnerable Express versions listed on the [Security updates page](/advanced/security-updates). もしそうであれば、安定版リリースのいずれかにアップデートしてください。 ## TLS を使用 -機密データを扱ったり転送したりする場合は、[Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) を使用して接続とデータを保護します。 この技術は、クライアントからサーバーに送信される前にデータを暗号化し、一般的な(そして簡単な)ハッキングを防ぎます。 機密データを扱ったり転送したりする場合は、[Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) を使用して接続とデータを保護します。 この技術は、クライアントからサーバーに送信される前にデータを暗号化し、一般的な(そして簡単な)ハッキングを防ぎます。 Ajax と POST リクエストは目に見えて明らかではなく、ブラウザーでは「非表示」に見えるかもしれません。 彼らのネットワークトラフィックは、[パケットスニッフィング](https://en.wikipedia.org/wiki/Packet_analyzer)と[man-in-the-middle攻撃](https://en.wikipedia.org/wiki/Man-in-the-middle_attack)に対して脆弱です。 +機密データを扱ったり転送したりする場合は、[Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) を使用して接続とデータを保護します。この技術は、クライアントからサーバーに送信される前にデータを暗号化し、一般的な(そして簡単な)ハッキングを防ぎます。機密データを扱ったり転送したりする場合は、[Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) を使用して接続とデータを保護します。 この技術は、クライアントからサーバーに送信される前にデータを暗号化し、一般的な(そして簡単な)ハッキングを防ぎます。 Ajax と POST リクエストは目に見えて明らかではなく、ブラウザーでは「非表示」に見えるかもしれません。 彼らのネットワークトラフィックは、[パケットスニッフィング](https://en.wikipedia.org/wiki/Packet_analyzer)と[man-in-the-middle攻撃](https://en.wikipedia.org/wiki/Man-in-the-middle_attack)に対して脆弱です。 -SSL(Secure Socket Layer)暗号化に精通しているかもしれません。 [TLS is simply the next progression of SSL](https://learn.microsoft.com/en-us/windows/win32/secauthn/tls-versus-ssl). 言い換えれば、以前SSLを使用していた場合は、TLSへのアップグレードを検討してください。 一般的に、Nginx は TLS を扱うことをお勧めします。 For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (TLSRef)](https://docs.tlsref.org/server-side-tls.html#recommended-configurations). +SSL(Secure Socket Layer)暗号化に精通しているかもしれません。 [TLS is simply the next progression of SSL](https://learn.microsoft.com/en-us/windows/win32/secauthn/tls-versus-ssl). 言い換えれば、以前SSLを使用していた場合は、TLSへのアップグレードを検討してください。一般的に、Nginx は TLS を扱うことをお勧めします。 For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (TLSRef)](https://docs.tlsref.org/server-side-tls.html#recommended-configurations). Also, a handy tool to get a free TLS certificate is [Let's Encrypt](https://letsencrypt.org/about/), a free, automated, and open certificate authority (CA) provided by the [Internet Security Research Group (ISRG)](https://www.abetterinternet.org/). ## ユーザー入力を信頼しない Webアプリケーションの場合、最も重要なセキュリティ要件の1つは、適切なユーザー入力検証と処理です。 これは多くの形態で来て、我々はここでそれらのすべてをカバーしません。 -最終的に、アプリケーションが受け入れるユーザー入力の種類を検証し、正しく処理する責任はあなたのものです。 これは多くの形態で来て、我々はここでそれらのすべてをカバーしません。 -最終的に、アプリケーションが受け入れるユーザー入力の種類を検証し、正しく処理する責任はあなたのものです。 +最終的に、アプリケーションが受け入れるユーザー入力の種類を検証し、正しく処理する責任はあなたのものです。これは多くの形態で来て、我々はここでそれらのすべてをカバーしません。最終的に、アプリケーションが受け入れるユーザー入力の種類を検証し、正しく処理する責任はあなたのものです。 ### 開いているリダイレクトを防止 @@ -49,7 +48,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) { @@ -63,7 +62,7 @@ app.use((req, res) => { [Helmet][helmet] は、HTTPヘッダーを適切に設定することで、よく知られているWeb脆弱性からアプリを保護するのに役立ちます。 -Helmet は、セキュリティ関連の HTTP レスポンスヘッダーを設定するミドルウェア機能です。 ヘルメットは、デフォルトで次のヘッダーを設定します。 ヘルメットは、デフォルトで次のヘッダーを設定します。 +Helmet は、セキュリティ関連の HTTP レスポンスヘッダーを設定するミドルウェア機能です。 ヘルメットは、デフォルトで次のヘッダーを設定します。ヘルメットは、デフォルトで次のヘッダーを設定します。 - `Content-Security-Policy`: 多くの攻撃を軽減するためにあなたのページで何が起こるかを許可する強力なリスト - `Cross-Origin-Opener-Policy`: あなたのページを分離するのに役立ちます @@ -76,10 +75,10 @@ Helmet は、セキュリティ関連の HTTP レスポンスヘッダーを設 - `X-Download-Options`: 強制的にダウンロードを保存します (Internet Explorerのみ) - `X-Frame-Options`: [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) 攻撃を軽減する従来のヘッダー - `X-Permitted-Cross-Domain-Policies`: Acrobat など、Adobe 製品のクロスドメイン動作を制御します -- `X-Powered-By`: Webサーバーに関する情報。 簡単な攻撃で使用できるため削除されました 簡単な攻撃で使用できるため削除されました +- `X-Powered-By`: Webサーバーに関する情報。 簡単な攻撃で使用できるため削除されました簡単な攻撃で使用できるため削除されました - `X-XSS-Protection`: [XSS アタック](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting)を軽減しようとするレガシーヘッダーが悪化するため、ヘルメットは無効にします -各ヘッダーは、設定または無効にできます。 詳細については、[its documentation website][helmet] をご覧ください。 詳細については、[its documentation website][helmet] をご覧ください。 +各ヘッダーは、設定または無効にできます。 詳細については、[its documentation website][helmet] をご覧ください。詳細については、[its documentation website][helmet] をご覧ください。 他のモジュールと同様にヘルメットをインストール: @@ -277,7 +276,7 @@ $ npm audit もっと安全な場合は、 [Snyk](https://snyk.io/) を検討してください。 -Snyk は [コマンド ライン ツール](https://www.npmjs.com/package/snyk) と [Github 統合](https://snyk.io/docs/github) の両方を提供しており、依存関係の既知の脆弱性についてアプリケーションを [Snyk のオープン ソース 脆弱性 データベース](https://snyk.io/vuln/) でチェックします。 CLI を以下のようにインストールします。 Install the CLI as follows: +Snyk は [コマンド ライン ツール](https://www.npmjs.com/package/snyk) と [Github 統合](https://docs.snyk.io/discover-snyk/getting-started) の両方を提供しており、依存関係の既知の脆弱性についてアプリケーションを [Snyk のオープン ソース 脆弱性 データベース](https://security.snyk.io/) でチェックします。 CLI を以下のようにインストールします。 Install the CLI as follows: ```bash $ npm install -g snyk @@ -294,7 +293,7 @@ $ snyk test Keep an eye out for [GitHub Advisory Database](https://github.com/advisories?query=ecosystem%3Anpm) or [Snyk](https://security.snyk.io/vuln/npm) advisories that may affect Express or other modules that your app uses. 一般的に、これらのデータベースは、Node セキュリティに関する知識とツールのための優れたリソースです。 -Finally, Express apps—like any other web apps—can be vulnerable to a variety of web-based attacks. Familiarize yourself with known [web vulnerabilities](https://www.owasp.org/www-project-top-ten/) and take precautions to avoid them. +Finally, Express apps—like any other web apps—can be vulnerable to a variety of web-based attacks. Familiarize yourself with known [web vulnerabilities](https://owasp.org/www-project-top-ten/) and take precautions to avoid them. ## その他の考慮事項 @@ -302,8 +301,8 @@ Finally, Express apps—like any other web apps—can be vulnerable to a - クロスサイト・スクリプティング(XSS)やコマンドインジェクション攻撃から保護するため、常にユーザー入力をフィルタリングしてサニタイズします。 - パラメータ化されたクエリまたは準備された文を使用してSQLインジェクション攻撃を防御します。 -- アプリケーションのSQLインジェクションの脆弱性を検出するには、オープンソースの [sqlmap](http://sqlmap.org/)ツールを使用してください。 +- アプリケーションのSQLインジェクションの脆弱性を検出するには、オープンソースの [sqlmap](https://sqlmap.org/)ツールを使用してください。 - SSL暗号の設定をテストするには、 [nmap](https://nmap.org/) と [sslyze](https://github.com/nabla-c0d3/sslyze) ツールを使用します。 キー、再ネゴシエーション、および証明書の有効性。 -- [safe-regex](https://www.npmjs.com/package/safe-regex) を使用して、正規表現が [正規表現 サービス妨害](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) 攻撃の影響を受けないようにしましょう。 +- [safe-regex](https://www.npmjs.com/package/safe-regex) を使用して、正規表現が [正規表現 サービス妨害](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) 攻撃の影響を受けないようにしましょう。 -[helmet]: https://helmetjs.github.io/ +[helmet]: https://helmet.js.org/ 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/advanced/security-updates.mdx b/src/content/pages/ja/advanced/security-updates.mdx index fee78e581a..6c998e4ed0 100644 --- a/src/content/pages/ja/advanced/security-updates.mdx +++ b/src/content/pages/ja/advanced/security-updates.mdx @@ -9,7 +9,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; Node.js の脆弱性は Express に直接影響します。 そのため、Node.js 脆弱性を監視する と最新の -安定版の Node.js を使用していることを確認してください。 そのため、Node.js +安定版の Node.js を使用していることを確認してください。そのため、Node.js 脆弱性を監視する と最新の 安定版の Node.js を使用していることを確認してください。 @@ -43,7 +43,7 @@ Express でセキュリティ上の脆弱性を発見したと思われる場合 - 4.16.0 - The dependency `forwarded` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-mpcf-4gmh-23w8). 依存関係の `forwarded` が [vulnerability](https://npmjs.com/advisories/527) に更新されました。 以下の API が使用されている場合、アプリケーションに影響を与える可能性があります: `req.host` 、 `req.hostname` 、 `req.ips` 、 `req.protocol` 。 - The dependency `mime` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-wrvr-8mpx-r7pp), but this issue does not impact Express. - - 依存関係の `send` が更新され、[Node.js 8.5.0 脆弱性](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/)に対する保護が提供されました。 これは、Express が特定の Node.js バージョン 8.5.0 で実行されることにのみ影響します。 これは、Express が特定の Node.js バージョン 8.5.0 で実行されることにのみ影響します。 + - 依存関係の `send` が更新され、[Node.js 8.5.0 脆弱性](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/)に対する保護が提供されました。 これは、Express が特定の Node.js バージョン 8.5.0 で実行されることにのみ影響します。これは、Express が特定の Node.js バージョン 8.5.0 で実行されることにのみ影響します。 - 4.15.5 - 依存関係の `debug` が [vulnerability](https://snyk.io/vuln/npm:debug:20170905) アドレスに更新されましたが、この問題は Express には影響しません。 - The dependency `fresh` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-9qj9-36jm-prpv). 依存関係の `fresh` が [vulnerability](https://npmjs.com/advisories/526) に更新されました。 `express.static` 、 `req.fresh` 、 `res.json` 、 `res.json` 、 `res.send` 、 `res.send` 、 `res.sendFile` 、 `res.sendFile` 、 `res.sendStatus` などのAPIが使用されると、アプリケーションに影響します。 @@ -58,7 +58,7 @@ Express でセキュリティ上の脆弱性を発見したと思われる場合 - 4.8.8 - `express.static` ([advisory](http://npmjs.com/advisories/32) , [CVE-2014-6394](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6394)のディレクトリトラバーサルの脆弱性を修正しました。 - 4.8.4 - - Node.js 0.10 は、`express.static` と `res.sendfile` に影響を与える特定の状況で `fd` をリークできます。 悪意のある要求は`fd`がリークし、最終的には`EMFILE`エラーとサーバーの応答性が低下する可能性があります。 悪意のある要求は`fd`がリークし、最終的には`EMFILE`エラーとサーバーの応答性が低下する可能性があります。 + - Node.js 0.10 は、`express.static` と `res.sendfile` に影響を与える特定の状況で `fd` をリークできます。 悪意のある要求は`fd`がリークし、最終的には`EMFILE`エラーとサーバーの応答性が低下する可能性があります。悪意のある要求は`fd`がリークし、最終的には`EMFILE`エラーとサーバーの応答性が低下する可能性があります。 - 4.8.0 - クエリ文字列に非常に高いインデックスを持つ疎行列は、プロセスがメモリ不足になり、サーバーがクラッシュする可能性があります。 - 非常にネストされたクエリ文字列オブジェクトは、プロセスをブロックし、サーバーが一時的に応答しないようにする可能性があります。 @@ -68,7 +68,7 @@ Express でセキュリティ上の脆弱性を発見したと思われる場合 **エクスプレス 3.x is END-OF-LIFE and no longer maintained** -3.x における既知のセキュリティとパフォーマンスの問題は、前回のアップデート(2015年8月1日)から解決されていません。 最新版のExpressをご利用いただくことを強くお勧めします。 +3.x における既知のセキュリティとパフォーマンスの問題は、前回のアップデート(2015年8月1日)から解決されていません。最新版のExpressをご利用いただくことを強くお勧めします。 3.x以降のアップグレードができない場合は、[Commercial Support Options](/support#commercial-support-options)をご検討ください。 @@ -81,7 +81,7 @@ Express でセキュリティ上の脆弱性を発見したと思われる場合 - 3.16.10 - `express.static`におけるディレクトリトラバーサルの脆弱性を修正しました。 - 3.16.6 - - Node.js 0.10 は、`express.static` と `res.sendfile` に影響を与える特定の状況で `fd` をリークできます。 悪意のある要求は`fd`がリークし、最終的には`EMFILE`エラーとサーバーの応答性が低下する可能性があります。 悪意のある要求は`fd`がリークし、最終的には`EMFILE`エラーとサーバーの応答性が低下する可能性があります。 + - Node.js 0.10 は、`express.static` と `res.sendfile` に影響を与える特定の状況で `fd` をリークできます。 悪意のある要求は`fd`がリークし、最終的には`EMFILE`エラーとサーバーの応答性が低下する可能性があります。悪意のある要求は`fd`がリークし、最終的には`EMFILE`エラーとサーバーの応答性が低下する可能性があります。 - 3.16.0 - クエリ文字列のインデックスが非常に高いスパース配列は、プロセスがメモリ不足になり、サーバーがクラッシュする可能性があります。 - 非常にネストされたクエリ文字列オブジェクトは、プロセスをブロックし、サーバーが一時的に応答しないようにする可能性があります。 diff --git a/src/content/pages/ja/guide/database-integration.mdx b/src/content/pages/ja/guide/database-integration.mdx index dfb086d24e..41bac35365 100644 --- a/src/content/pages/ja/guide/database-integration.mdx +++ b/src/content/pages/ja/guide/database-integration.mdx @@ -6,7 +6,7 @@ description: MongoDB、MySQL、PostgreSQLなどのセットアップ例を含む import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -Expressアプリケーションにデータベースを接続する機能を追加することは、アプリケーション内のデータベースに適切なNode.jsドライバをロードするだけです。 このドキュメントでは、Express アプリケーションで最も人気のある Node.js モジュールのいくつかを追加して使用する方法を簡単に説明します。 +Expressアプリケーションにデータベースを接続する機能を追加することは、アプリケーション内のデータベースに適切なNode.jsドライバをロードするだけです。このドキュメントでは、Express アプリケーションで最も人気のある Node.js モジュールのいくつかを追加して使用する方法を簡単に説明します。 - [Cassandra](#cassandra) - [Couchbase](#couchbase) @@ -24,7 +24,7 @@ Expressアプリケーションにデータベースを接続する機能を追 -これらのデータベースドライバは、利用可能な多くの中にあります。 その他のオプションについては、 +これらのデータベースドライバは、利用可能な多くの中にあります。その他のオプションについては、 [npm](https://www.npmjs.com/) サイトを検索してください。 diff --git a/src/content/pages/ja/guide/migrating-4.mdx b/src/content/pages/ja/guide/migrating-4.mdx index 15d828e277..ad9a5726c9 100644 --- a/src/content/pages/ja/guide/migrating-4.mdx +++ b/src/content/pages/ja/guide/migrating-4.mdx @@ -6,7 +6,7 @@ description: Express.jsアプリケーションをバージョン3からバー import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -エクスプレス4はエクスプレス3からの変更です。 つまり、Expressバージョンを依存関係で更新すると、既存のExpress 3アプリは動作しなくなります。 つまり、Expressバージョンを依存関係で更新すると、既存のExpress 3アプリは動作しなくなります。 +エクスプレス4はエクスプレス3からの変更です。 つまり、Expressバージョンを依存関係で更新すると、既存のExpress 3アプリは動作しなくなります。つまり、Expressバージョンを依存関係で更新すると、既存のExpress 3アプリは動作しなくなります。 この記事のカバー: @@ -37,7 +37,7 @@ Express is now an independent routing and middleware web framework, and Express versioning and releases are not affected by middleware updates. 組み込みのミドルウェアがなければ、アプリケーションの実行に必要なすべての -ミドルウェアを明示的に追加する必要があります。 以下の手順に従ってください: 以下の手順に従ってください: +ミドルウェアを明示的に追加する必要があります。 以下の手順に従ってください:以下の手順に従ってください: 1. モジュールをインストール: `npm install --save \` 2. アプリでは、次のモジュールを必要とします: `require('module-name')` @@ -45,139 +45,29 @@ Express versioning and releases are not affected by middleware updates. 以下の表は、Express 4でのExpress 3ミドルウェアとそのミドルウェアを示しています。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
エクスプレス 3エクスプレス 4
- express.bodyParser - - body-parser + - multer -
- express.compress - - 圧縮 -
- express.cookieSession - - クッキーセッション -
- express.cookieParser - - クッキーパーサ -
- express.logger - - モーガン -
- express.session - - express-session -
- express.favicon - - サービスファビコン -
- express.responseTime - - 応答時間 -
- express.errorHandler - - errorhandler -
- express.methodOverride - - メソッド-オーバーライド -
- express.timeout - - 接続タイムアウト -
- express.vhost - - vhost -
- express.csrf - - csurf -
- express.directory - - サーブインデックス -
- express.static - - スタティック -
+| Express 3 | Express 4 | +| ------------------------ | ------------------------------------------------------------------------------------------------------- | +| `express.bodyParser` | [body-parser](https://github.com/expressjs/body-parser) + [multer](https://github.com/expressjs/multer) | +| `express.compress` | [compression](https://github.com/expressjs/compression) | +| `express.cookieSession` | [cookie-session](https://github.com/expressjs/cookie-session) | +| `express.cookieParser` | [cookie-parser](https://github.com/expressjs/cookie-parser) | +| `express.logger` | [morgan](https://github.com/expressjs/morgan) | +| `express.session` | [express-session](https://github.com/expressjs/session) | +| `express.favicon` | [serve-favicon](https://github.com/expressjs/serve-favicon) | +| `express.responseTime` | [response-time](https://github.com/expressjs/response-time) | +| `express.errorHandler` | [errorhandler](https://github.com/expressjs/errorhandler) | +| `express.methodOverride` | [method-override](https://github.com/expressjs/method-override) | +| `express.timeout` | [connect-timeout](https://github.com/expressjs/timeout) | +| `express.vhost` | [vhost](https://github.com/expressjs/vhost) | +| `express.csrf` | [csurf](https://github.com/expressjs/csurf) | +| `express.directory` | [serve-index](https://github.com/expressjs/serve-index) | +| `express.static` | [serve-static](https://github.com/expressjs/serve-static) | Here is the [complete list](https://github.com/senchalabs/connect#middleware) of Express 4 middleware. ほとんどの場合、古いバージョン3のミドルウェアを のExpress 4に置き換えることができます。 詳細については、 -GitHub のモジュールドキュメントを参照してください。 詳細については、 +GitHub のモジュールドキュメントを参照してください。詳細については、 GitHub のモジュールドキュメントを参照してください。 #### `app.use`はパラメータを受け付けます @@ -311,80 +201,21 @@ middleware that is specific to the route. 以下の表は、Express 4の他の重要な変更点を示しています。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
オブジェクト説明
Node.jsExpress 4 は Node.js 0.10.x 以降が必要で、Node.js 0.8.x のサポートを廃止しました。
`http.createServer()` - `http`モジュールは、 - (socket.io/SPDY/HTTPS)で直接動作する必要がない限り、もはや必要ありません。 - アプリは、`app.listen()`関数を使用して起動できます。 The app can be started by using the - `app.listen()` function. -
`app.configure()` - The `app.configure()` function has been removed. Use the `process.env.NODE_ENV` or - `app.get('env')` function to detect the environment and configure the app accordingly. -
`json spaces` - Express 4では、`json spaces` アプリケーションプロパティはデフォルトで無効になっています。 -
`req.accepted()` - `req.accepts()`、`req.acceptsEncodings()`、`req.acceptsCharsets()`、および - `req.acceptsLanguages()`を使用してください。 -
`res.location()`相対URLを解決しなくなりました。
`req.params`配列で、現在はオブジェクトです。
`res.locals`関数でした; 今はオブジェクトです。
`res.headerSent``res.headersSent` に変更しました。
`app.route``app.mountpath` として利用可能になりました。
`res.on('header')`削除しました。
`res.charset`削除しました。
`res.setHeader('Set-Cookie', val)` - 機能は基本的なクッキー値の設定に限定されるようになりました。 追加された 機能には、 - `res.cookie()` を使用します。 Use `res.cookie()` for added functionality. -
+| Object | 説明 | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Node.js | Express 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x. | +| `http.createServer()` | The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). The app can be started by using the `app.listen()` function. | +| `app.configure()` | The `app.configure()` function has been removed. Use the `process.env.NODE_ENV` or `app.get('env')` function to detect the environment and configure the app accordingly. | +| `json spaces` | Express 4では、`json spaces` アプリケーションプロパティはデフォルトで無効になっています。 | +| `req.accepted()` | `req.accepts()`、`req.acceptsEncodings()`、`req.acceptsCharsets()`、および `req.acceptsLanguages()`を使用してください。 | +| `res.location()` | No longer resolves relative URLs. | +| `req.params` | Was an array; now an object. | +| `res.locals` | Was a function; now an object. | +| `res.headerSent` | Changed to `res.headersSent`. | +| `app.route` | Now available as `app.mountpath`. | +| `res.on('header')` | Removed. | +| `res.charset` | Removed. | +| `res.setHeader('Set-Cookie', val)` | 機能は基本的なクッキー値の設定に限定されるようになりました。 追加された 機能には、 `res.cookie()` を使用します。 Use `res.cookie()` for added functionality. | ## アプリの移行例 diff --git a/src/content/pages/ja/guide/migrating-5.mdx b/src/content/pages/ja/guide/migrating-5.mdx index 9f43445760..bf8e421e1d 100644 --- a/src/content/pages/ja/guide/migrating-5.mdx +++ b/src/content/pages/ja/guide/migrating-5.mdx @@ -6,15 +6,15 @@ description: Express.jsアプリケーションをバージョン4からバー import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -エクスプレス5はエクスプレス4と大きく異なりません。 同じ基本APIを維持していますが、以前のバージョンとの互換性を破る変更はまだあります。 したがって、Express 5を使用するように更新すると、Express 4で構築されたアプリケーションが動作しない可能性があります。 したがって、Express 5を使用するように更新すると、Express 4で構築されたアプリケーションが動作しない可能性があります。 +エクスプレス5はエクスプレス4と大きく異なりません。 同じ基本APIを維持していますが、以前のバージョンとの互換性を破る変更はまだあります。 したがって、Express 5を使用するように更新すると、Express 4で構築されたアプリケーションが動作しない可能性があります。したがって、Express 5を使用するように更新すると、Express 4で構築されたアプリケーションが動作しない可能性があります。 ## インストール -このバージョンをインストールするには、**Node.js version 18以上**が必要です。 次に、アプリケーションディレクトリで次のコマンドを実行します。 次に、アプリケーションディレクトリで次のコマンドを実行します。 +このバージョンをインストールするには、**Node.js version 18以上**が必要です。 次に、アプリケーションディレクトリで次のコマンドを実行します。次に、アプリケーションディレクトリで次のコマンドを実行します。 -その後、自動テストを実行して何が失敗するかを確認し、以下に示すアップデートに従って問題を解決することができます。 テストに失敗した後、どのエラーが発生したかを確認するためにアプリケーションを実行します。 サポートされていないメソッドやプロパティを使用している場合は、すぐに確認できます。 テストに失敗した後、どのエラーが発生したかを確認するためにアプリケーションを実行します。 サポートされていないメソッドやプロパティを使用している場合は、すぐに確認できます。 +その後、自動テストを実行して何が失敗するかを確認し、以下に示すアップデートに従って問題を解決することができます。 テストに失敗した後、どのエラーが発生したかを確認するためにアプリケーションを実行します。 サポートされていないメソッドやプロパティを使用している場合は、すぐに確認できます。テストに失敗した後、どのエラーが発生したかを確認するためにアプリケーションを実行します。サポートされていないメソッドやプロパティを使用している場合は、すぐに確認できます。 ## Express 5 Codemods @@ -32,13 +32,13 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa ## 削除されたメソッドとプロパティ -これらのメソッドやプロパティをアプリケーションで使用すると、クラッシュします。 したがって、バージョン5にアップデートした後、アプリを変更する必要があります。 +これらのメソッドやプロパティをアプリケーションで使用すると、クラッシュします。したがって、バージョン5にアップデートした後、アプリを変更する必要があります。 ### app.del() -Express 5では、`app.del()`関数がサポートされなくなりました。 この関数を使うと、エラーがスローされます。 HTTP DELETEルートを登録するには、代わりに`app.delete()`関数を使用します。 この関数を使うと、エラーがスローされます。 HTTP DELETEルートを登録するには、代わりに`app.delete()`関数を使用します。 +Express 5では、`app.del()`関数がサポートされなくなりました。 この関数を使うと、エラーがスローされます。 HTTP DELETEルートを登録するには、代わりに`app.delete()`関数を使用します。この関数を使うと、エラーがスローされます。 HTTP DELETEルートを登録するには、代わりに`app.delete()`関数を使用します。 -`delete`はJavaScriptで予約されているキーワードであるため、最初は`delete`の代わりに`del`が使用されていました。 しかし、ECMAScript 6 では、 `delete` などの予約キーワードをプロパティ名として使用することができます。 しかし、ECMAScript 6 では、 `delete` などの予約キーワードをプロパティ名として使用することができます。 +`delete`はJavaScriptで予約されているキーワードであるため、最初は`delete`の代わりに`del`が使用されていました。 しかし、ECMAScript 6 では、 `delete` などの予約キーワードをプロパティ名として使用することができます。しかし、ECMAScript 6 では、 `delete` などの予約キーワードをプロパティ名として使用することができます。 #### 更新方法 @@ -98,7 +98,7 @@ This should not affect your code if you follow the Express 4 documentation of [a ### req.param(name) -これは、潜在的に混乱し、フォームデータを取得する危険な方法が削除されました。 これは、潜在的に混乱し、フォームデータを取得する危険な方法が削除されました。 ここで、`req.params`、`req.body`、または`req.query`オブジェクトの中で、送信されたパラメータ名を具体的に探す必要があります。 +これは、潜在的に混乱し、フォームデータを取得する危険な方法が削除されました。これは、潜在的に混乱し、フォームデータを取得する危険な方法が削除されました。 ここで、`req.params`、`req.body`、または`req.query`オブジェクトの中で、送信されたパラメータ名を具体的に探す必要があります。 #### 更新方法 @@ -142,7 +142,7 @@ Express 5 では署名 `res.jsonp(obj, status)` がサポートされなくな ### res.jsonp(obj, status) -Express 5 では署名 `res.jsonp(obj, status)` がサポートされなくなりました。 代わりに、ステータスを設定し、 `res.jsonp()` メソッドを次のようにチェーンします。`res.status(status).jsonp(obj)` 。 +Express 5 では署名 `res.jsonp(obj, status)` がサポートされなくなりました。代わりに、ステータスを設定し、 `res.jsonp()` メソッドを次のようにチェーンします。`res.status(status).jsonp(obj)` 。 #### 更新方法 @@ -161,7 +161,7 @@ Express 5 では署名 `res.jsonp(obj, status)` がサポートされなくな ### res.redirect(url, status) -Express 5 では署名 `res.redirect(url, status)` がサポートされなくなりました。 代わりに、`res.redirect(status, url)` という署名を使用します。 代わりに、`res.redirect(status, url)` という署名を使用します。 +Express 5 では署名 `res.redirect(url, status)` がサポートされなくなりました。 代わりに、`res.redirect(status, url)` という署名を使用します。代わりに、`res.redirect(status, url)` という署名を使用します。 #### 更新方法 @@ -185,7 +185,7 @@ Express 5 では署名 `res.redirect(url, status)` がサポートされなく ### res.redirect('back') と res.location('back') -Express 5では、`res.redirect()`と`res.location()`メソッドの魔法文字列`back`がサポートされなくなりました。 代わりに、 `req.get('Referrer') |'/'`の値を使用して前のページにリダイレクトします。 Express 4 では、`res.redirect('back')` と `res.location('back')` メソッドは廃止されました。 代わりに、 `req.get('Referrer') |'/'`の値を使用して前のページにリダイレクトします。 Express 4 では、`res.redirect('back')` と `res.location('back')` メソッドは廃止されました。 +Express 5では、`res.redirect()`と`res.location()`メソッドの魔法文字列`back`がサポートされなくなりました。 代わりに、 `req.get('Referrer') |'/'`の値を使用して前のページにリダイレクトします。 Express 4 では、`res.redirect('back')` と `res.location('back')` メソッドは廃止されました。代わりに、 `req.get('Referrer') |'/'`の値を使用して前のページにリダイレクトします。 Express 4 では、`res.redirect('back')` と `res.location('back')` メソッドは廃止されました。 #### 更新方法 @@ -204,7 +204,7 @@ Express 5では、`res.redirect()`と`res.location()`メソッドの魔法文字 ### res.send(body, status) -Express 5 では署名 `res.send(obj, status)` がサポートされなくなりました。 代わりに、ステータスを設定し、 `res.status(status).send(obj)` のように、 `res.send()` メソッドを連鎖させます。 代わりに、ステータスを設定し、 `res.status(status).send(obj)` のように、 `res.send()` メソッドを連鎖させます。 +Express 5 では署名 `res.send(obj, status)` がサポートされなくなりました。 代わりに、ステータスを設定し、 `res.status(status).send(obj)` のように、 `res.send()` メソッドを連鎖させます。代わりに、ステータスを設定し、 `res.status(status).send(obj)` のように、 `res.send()` メソッドを連鎖させます。 #### 更新方法 @@ -223,7 +223,7 @@ Express 5 では署名 `res.send(obj, status)` がサポートされなくなり ### res.send(status -Express 5では、`status` が数値である署名 `res.send(status)` がサポートされなくなりました。 代わりに、 `res を使ってください。 endStatus(statusCode)` 関数は、HTTP レスポンスヘッダーのステータスコードを設定し、コードのテキストバージョンを送信します。 "Not Found", "Internal Server Error"など。 +Express 5では、`status` が数値である署名 `res.send(status)` がサポートされなくなりました。代わりに、 `res を使ってください。 endStatus(statusCode)` 関数は、HTTP レスポンスヘッダーのステータスコードを設定し、コードのテキストバージョンを送信します。 "Not Found", "Internal Server Error"など。 \`res を使って数字を送る必要がある場合。 end()関数は、数字を文字列に変換するために引用符で囲みます Expressはサポートされていない古い署名を使用しようとしないようにします。 #### 更新方法 @@ -262,7 +262,7 @@ Express 5では、`status` が数値である署名 `res.send(status)` がサポ ### res.sendFile() オプション -`res.sendFile()`の`hidden`と`from`オプションはサポートされなくなりました。 代わりに `dotfiles` と `root` を使用してください。 代わりに `dotfiles` と `root` を使用してください。 +`res.sendFile()`の`hidden`と`from`オプションはサポートされなくなりました。 代わりに `dotfiles` と `root` を使用してください。代わりに `dotfiles` と `root` を使用してください。 The `dotfiles` option applies to hidden directories in the path as well as hidden files. For example, a file served from an absolute path like `/var/www/app/.cache/index.html` now requires `dotfiles: 'allow'`, even though `index.html` is not a dotfile. In Express 4 a hidden directory in the path was served by default; Express 5 returns `404` unless you opt in. @@ -295,7 +295,7 @@ If you serve an absolute path that contains a hidden directory, opt in with `dot ### express.static() オプション -`express.static()`の`hidden`と`from`オプションはサポートされなくなりました。 代わりに `dotfiles` と `root` を使用してください。 `from`はAPIでは文書化されていませんが、`root`のエイリアスとして受け入れられています。 `dotfiles` のデフォルト値は `ignore"` になりました。 代わりに `dotfiles` と `root` を使用してください。 `from`はAPIでは文書化されていませんが、`root`のエイリアスとして受け入れられています。 `dotfiles` のデフォルト値は `ignore"` になりました。 +`express.static()`の`hidden`と`from`オプションはサポートされなくなりました。 代わりに `dotfiles` と `root` を使用してください。 `from`はAPIでは文書化されていませんが、`root`のエイリアスとして受け入れられています。 `dotfiles` のデフォルト値は `ignore"` になりました。代わりに `dotfiles` と `root` を使用してください。 `from`はAPIでは文書化されていませんが、`root`のエイリアスとして受け入れられています。 `dotfiles` のデフォルト値は `ignore"` になりました。 The `dotfiles` check now also applies to hidden **directories** in the request path, not just hidden files. A request like `GET /.well-known/acme-challenge/...` that was served by default in Express 4 now returns `404` unless you set `dotfiles: 'allow'`. This only affects the part of the path relative to the configured `root`; a hidden directory in `root` itself is unaffected. @@ -348,15 +348,15 @@ MIME タイプの値を扱うには、[`mime-types` package](https://github.com/ ### MIMEタイプの変更 -[`mime-db`](https://github.com/jshttp/mime-db)の更新により、いくつかの MIME タイプが変更されました。 これらの変更は `express.static()` と `res.sendFile()` にのみ影響します。 [`mime-db`](https://github.com/jshttp/mime-db)の更新により、いくつかの MIME タイプが変更されました。 これらの変更は `express.static()` と `res.sendFile()` にのみ影響します。 変更の完全なリストについては、[`mime-db` changelog](https://github.com/jshttp/mime-db/blob/HEAD/HISTORY.md) を参照してください。 +[`mime-db`](https://github.com/jshttp/mime-db)の更新により、いくつかの MIME タイプが変更されました。これらの変更は `express.static()` と `res.sendFile()` にのみ影響します。 [`mime-db`](https://github.com/jshttp/mime-db)の更新により、いくつかの MIME タイプが変更されました。 これらの変更は `express.static()` と `res.sendFile()` にのみ影響します。 変更の完全なリストについては、[`mime-db` changelog](https://github.com/jshttp/mime-db/blob/HEAD/HISTORY.md) を参照してください。 -Express 4 は `mime-db` バージョン **1.52.0** を使用し、Express 5 は IANA や その他のMIME タイプの仕様への更新を反映した新しいバージョンを使用します。 最も注目すべき変更は、JavaScript ファイル (`.js`) が `application/javascript` の代わりに `text/javascript` として提供されるようになったことです。 最も注目すべき変更は、JavaScript ファイル (`.js`) が `application/javascript` の代わりに `text/javascript` として提供されるようになったことです。 +Express 4 は `mime-db` バージョン **1.52.0** を使用し、Express 5 は IANA や その他のMIME タイプの仕様への更新を反映した新しいバージョンを使用します。 最も注目すべき変更は、JavaScript ファイル (`.js`) が `application/javascript` の代わりに `text/javascript` として提供されるようになったことです。最も注目すべき変更は、JavaScript ファイル (`.js`) が `application/javascript` の代わりに `text/javascript` として提供されるようになったことです。 Express 5 では、`mime-db` アップデートからの MIME タイプへの変更は、壊れた変更とはみなされません。 MIMEタイプはマイナーバージョンやパッチバージョン間で変更される可能性があるため、依存関係を更新する際は注意が必要です。 ### express:routerデバッグログ -Expressチームが管理する別の依存関係([`router`](https://github.com/pillarjs/router)) によりルータの処理ロジックが実行されるようになりました。 デバッグログは別の名前空間に移動しました Express 5.1以前はデバッグログは存在しませんでした。 それらを取得するには、最新のExpress 5バージョンに更新するか、`package-lock.json`の`router`パッケージを更新してください。 Express 5.1以前はデバッグログは存在しませんでした。 それらを取得するには、最新のExpress 5バージョンに更新するか、`package-lock.json`の`router`パッケージを更新してください。 +Expressチームが管理する別の依存関係([`router`](https://github.com/pillarjs/router)) によりルータの処理ロジックが実行されるようになりました。 デバッグログは別の名前空間に移動しました Express 5.1以前はデバッグログは存在しませんでした。 それらを取得するには、最新のExpress 5バージョンに更新するか、`package-lock.json`の`router`パッケージを更新してください。 Express 5.1以前はデバッグログは存在しませんでした。それらを取得するには、最新のExpress 5バージョンに更新するか、`package-lock.json`の`router`パッケージを更新してください。 | v4 | v5 | | -------------------------- | ----------------------------------- | @@ -374,7 +374,7 @@ Expressチームが管理する別の依存関係([`router`](https://github.com/ ## 変更済み -これらの API はまだ存在しますが、動作は変更されています。 これらの変更を確認して、アプリが正常に動作することを確認してください。 これらの変更を確認して、アプリが正常に動作することを確認してください。 +これらの API はまだ存在しますが、動作は変更されています。 これらの変更を確認して、アプリが正常に動作することを確認してください。これらの変更を確認して、アプリが正常に動作することを確認してください。 ### パス経路一致の構文 @@ -425,13 +425,13 @@ Expressチームが管理する別の依存関係([`router`](https://github.com/ ### ミドルウェアとハンドラーから取り扱われる拒否された約束。 -rejected promiseを返すリクエストミドルウェアとハンドラは、「Error」として拒否された値をエラー処理ミドルウェアに転送することで処理されるようになりました。 つまり、 `async` 関数をミドルウェアとして、ハンドラを使うのはこれまで以上に簡単です。 rejected promiseを返すリクエストミドルウェアとハンドラは、「Error」として拒否された値をエラー処理ミドルウェアに転送することで処理されるようになりました。 つまり、 `async` 関数をミドルウェアとして、ハンドラを使うのはこれまで以上に簡単です。 `async` 関数でエラーがスローされるか、拒否された Promise が async 関数内で `await`ed になります。 これらのエラーは、`next(err)`を呼び出すかのようにエラーハンドラに渡されます。 +rejected promiseを返すリクエストミドルウェアとハンドラは、「Error」として拒否された値をエラー処理ミドルウェアに転送することで処理されるようになりました。つまり、 `async` 関数をミドルウェアとして、ハンドラを使うのはこれまで以上に簡単です。 rejected promiseを返すリクエストミドルウェアとハンドラは、「Error」として拒否された値をエラー処理ミドルウェアに転送することで処理されるようになりました。 つまり、 `async` 関数をミドルウェアとして、ハンドラを使うのはこれまで以上に簡単です。 `async` 関数でエラーがスローされるか、拒否された Promise が async 関数内で `await`ed になります。 これらのエラーは、`next(err)`を呼び出すかのようにエラーハンドラに渡されます。 Express でのエラー処理の詳細については、[Error handling documentation](/guide/error-handling)を参照してください。 #### 更新方法 -手動でエラーをキャッチせずに `async/await` を直接使用できるようになりました。 手動でエラーをキャッチせずに `async/await` を直接使用できるようになりました。 `getUserById` がエラーまたは拒否をスローした場合、`next` は拒否された値で自動的に呼び出されます。 +手動でエラーをキャッチせずに `async/await` を直接使用できるようになりました。手動でエラーをキャッチせずに `async/await` を直接使用できるようになりました。 `getUserById` がエラーまたは拒否をスローした場合、`next` は拒否された値で自動的に呼び出されます。 ```diff -app.get('/user/:id', (req, res, next) => { @@ -460,11 +460,11 @@ Express でのエラー処理の詳細については、[Error handling document ### express.static dotfiles -`express.static` ミドルウェアの `dotfiles` オプションのデフォルトは `ignore"` になりました。 Express 4では、デフォルトでドットファイルが提供されました。 結果として、`のようにドット(`.`)で始まるディレクトリ内のファイル。 ell-known`はアクセスできなくなり、**404 Not Found**エラーが返されます。 これにより、Android App Links や Apple Universal Link などのドットディレクトリの提供に依存する機能が壊れる可能性があります。 +`express.static` ミドルウェアの `dotfiles` オプションのデフォルトは `ignore"` になりました。 Express 4では、デフォルトでドットファイルが提供されました。結果として、`のようにドット(`.`)で始まるディレクトリ内のファイル。 ell-known`はアクセスできなくなり、**404 Not Found**エラーが返されます。これにより、Android App Links や Apple Universal Link などのドットディレクトリの提供に依存する機能が壊れる可能性があります。 #### 更新方法 -`dotfiles: "allow"`オプションを使用して、特定のドットディレクトリを明示的に提供します。 これにより、意図したドットディレクトリのみを安全に提供し、他のドットファイルのデフォルトの安全な動作を維持することができます。 これにより、意図したドットディレクトリのみを安全に提供し、他のドットファイルのデフォルトの安全な動作を維持することができます。 +`dotfiles: "allow"`オプションを使用して、特定のドットディレクトリを明示的に提供します。 これにより、意図したドットディレクトリのみを安全に提供し、他のドットファイルのデフォルトの安全な動作を維持することができます。これにより、意図したドットディレクトリのみを安全に提供し、他のドットファイルのデフォルトの安全な動作を維持することができます。 ```diff +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })); @@ -493,8 +493,7 @@ Register each parameter name with its own `router.param()` call: ### app.listen Express 5 では、サーバーがエラーイベントを受信したときに `app.listen` メソッドがユーザーが提供するコールバック関数を呼び出します。 Express 4では、そのようなエラーがスローされます。 この変更により、エラー処理の責任が Express 5 のコールバック関数に移行されます。 エラーがある場合は、コールバックに引数として渡されます。 -例: Express 4では、そのようなエラーがスローされます。 この変更により、エラー処理の責任が Express 5 のコールバック関数に移行されます。 エラーがある場合は、コールバックに引数として渡されます。 -例: +例: Express 4では、そのようなエラーがスローされます。この変更により、エラー処理の責任が Express 5 のコールバック関数に移行されます。エラーがある場合は、コールバックに引数として渡されます。例: ```js ins={2-4} const server = app.listen(8080, '0.0.0.0', (error) => { @@ -507,7 +506,7 @@ const server = app.listen(8080, '0.0.0.0', (error) => { ### app.router -Express 4 で削除された `app.router` オブジェクトは、Express 5 で復活しました。 新しいバージョンでは、このオブジェクトはベース Express ルータへの単なる参照です。 アプリが明示的にロードしなければならなかったExpress 3とは異なります。 新しいバージョンでは、このオブジェクトはベース Express ルータへの単なる参照です。 アプリが明示的にロードしなければならなかったExpress 3とは異なります。 +Express 4 で削除された `app.router` オブジェクトは、Express 5 で復活しました。 新しいバージョンでは、このオブジェクトはベース Express ルータへの単なる参照です。 アプリが明示的にロードしなければならなかったExpress 3とは異なります。新しいバージョンでは、このオブジェクトはベース Express ルータへの単なる参照です。 アプリが明示的にロードしなければならなかったExpress 3とは異なります。 ### req.body @@ -529,7 +528,7 @@ Express 4では、`req.host`関数がポート番号を間違って剥奪しま ### req.params -`req.params` オブジェクトに文字列パスを使用する際に **null プロトタイプ** が追加されました。 しかし、パスが正規表現で定義されている場合、`req.params` は通常のプロトタイプを持つ標準オブジェクトのままです。 さらに、2つの重要な行動変更があります。 しかし、パスが正規表現で定義されている場合、`req.params` は通常のプロトタイプを持つ標準オブジェクトのままです。 さらに、2つの重要な行動変更があります。 +`req.params` オブジェクトに文字列パスを使用する際に **null プロトタイプ** が追加されました。 しかし、パスが正規表現で定義されている場合、`req.params` は通常のプロトタイプを持つ標準オブジェクトのままです。 さらに、2つの重要な行動変更があります。しかし、パスが正規表現で定義されている場合、`req.params` は通常のプロトタイプを持つ標準オブジェクトのままです。さらに、2つの重要な行動変更があります。 **ワイルドカードパラメータは配列になりました:** @@ -572,7 +571,7 @@ Express 4では、マッチしないワイルドカードは空文字列(`'`)で ### req.query -`req.query` プロパティはもはや書き込み可能なプロパティではなく、代わりにゲッターです。 デフォルトのクエリパーサが"extended"から"simple"に変更されました。 デフォルトのクエリパーサが"extended"から"simple"に変更されました。 +`req.query` プロパティはもはや書き込み可能なプロパティではなく、代わりにゲッターです。 デフォルトのクエリパーサが"extended"から"simple"に変更されました。デフォルトのクエリパーサが"extended"から"simple"に変更されました。 ```js del={3} app.get('/search', (req, res) => { diff --git a/src/content/pages/ja/resources/contributing.mdx b/src/content/pages/ja/resources/contributing.mdx index c922887708..4ded12f7e0 100644 --- a/src/content/pages/ja/resources/contributing.mdx +++ b/src/content/pages/ja/resources/contributing.mdx @@ -5,7 +5,7 @@ description: Express.jsに貢献する方法については、問題の報告、 import Alert from '@components/primitives/Alert/Alert.astro'; -Express is an [OpenJS Foundation](https://openjsf.org/) project spread across three GitHub organizations: [expressjs](https://github.com/expressjs), [pillarjs](https://github.com/pillarjs), and [jshttp](https://github.com/jshttp). バグの報告、ドキュメントの改善、コードの提出など、すべての貢献は歓迎します。 以下のガイドラインでは、プロジェクトの運営方法と参加方法について説明します。 以下のガイドラインでは、プロジェクトの運営方法と参加方法について説明します。 +Express is an [OpenJS Foundation](https://openjsf.org/) project spread across three GitHub organizations: [expressjs](https://github.com/expressjs), [pillarjs](https://github.com/pillarjs), and [jshttp](https://github.com/jshttp). バグの報告、ドキュメントの改善、コードの提出など、すべての貢献は歓迎します。 以下のガイドラインでは、プロジェクトの運営方法と参加方法について説明します。以下のガイドラインでは、プロジェクトの運営方法と参加方法について説明します。 ## 技術委員会 @@ -33,22 +33,22 @@ Express技術委員会は、アクティブなプロジェクトメンバーで ### ログの問題 -質問または問題の問題を記録します。 質問または問題の問題を記録します。 When in doubt, log an issue, and +質問または問題の問題を記録します。質問または問題の問題を記録します。 When in doubt, log an issue, and any additional policies about what to include will be provided in the responses. 唯一 例外は、私的に送信されるべきセキュリティディスクロージャーです。 コミッターはあなたを別のリポジトリに誘導し、追加の説明を求め、問題が解決される前に 適切なメタデータを追加することができます。 -礼儀正しく、尊敬してください。 礼儀正しく、尊敬してください。 すべての参加者は、 +礼儀正しく、尊敬してください。礼儀正しく、尊敬してください。 すべての参加者は、 プロジェクトの行動規範に従うことが期待されます。 ### 貢献 このリポジトリのリソースへの変更は、プルリクエストでなければなりません。 これは、ドキュメント、コード、バイナリファイルなどのすべての変更 に適用されます。 長期的なコミッターやTCメンバーであっても、 -プルリクエストを使用する必要があります。 これは、ドキュメント、コード、バイナリファイルなどのすべての変更 -に適用されます。 長期的なコミッターやTCメンバーであっても、 +プルリクエストを使用する必要があります。これは、ドキュメント、コード、バイナリファイルなどのすべての変更 +に適用されます。長期的なコミッターやTCメンバーであっても、 プルリクエストを使用する必要があります。 レビューされずにプルリクエストをマージすることはできません。 @@ -60,8 +60,7 @@ any additional policies about what to include will be provided in the responses. の週末やその他の休暇期間にも配慮しなければならず、アクティブなコミッターが 議論とレビューのプロセスに参加するまでの合理的な時間を確保することができます。 -各コントリビューションのデフォルトは、コミッターが異議を持たない場合に受け入れられることです。 -各コントリビューションのデフォルトは、コミッターが異議を持たない場合に受け入れられることです。 +各コントリビューションのデフォルトは、コミッターが異議を持たない場合に受け入れられることです。各コントリビューションのデフォルトは、コミッターが異議を持たない場合に受け入れられることです。 During a review, committers may also request that a specific contributor who is most versed in a particular area gives a "LGTM" before the PR can be merged. 土地への貢献のための追加の「サインオフ」 プロセスはありません。 Once all issues brought by committers are addressed it can @@ -74,7 +73,7 @@ be landed by any committer. もし貢献が論争の的であり、コミッターが の着陸方法について同意できない場合、または着陸すべき場合は、TCにエスカレートさせる必要があります。 TCメンバーは、決議を見つけるために、保留中の貢献について定期的に -議論すべきです。 解決のためにTCには +議論すべきです。解決のためにTCには 少数の問題しか持ち込まれず、その議論とコミッター間の 妥協がデフォルトの解決メカニズムであることが期待されます。 @@ -85,10 +84,10 @@ be landed by any committer. Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate a new triager. トリアガーになることに興味があるなら 私たちの最善のアドバイスは、トリアージやプルリクエストを支援することによって、コミュニティで -積極的に参加することです。 また、 +積極的に参加することです。また、 は、TC会議に参加したり、Slack の議論に参加したりするなど、他のコミュニティ活動に参加することをお勧めします。 If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd -be willing to support you. 同意すれば、指名を正式化するプルリクエストを作成できます。 指名に異議を申し立てた場合、トリアージチームは関与する個人と協力し、解決策を見つける責任があります。 +be willing to support you. 同意すれば、指名を正式化するプルリクエストを作成できます。指名に異議を申し立てた場合、トリアージチームは関与する個人と協力し、解決策を見つける責任があります。 You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) if you have questions or need guidance. @@ -103,10 +102,8 @@ if you have questions or need guidance. ### TC プロセス -TCは、TCにエスカレートされた問題について「コンセンサスを求める」プロセスを使用します。 -グループは、TCメンバーの間に開かれた異議を持たない決議を見つけようとします。 -異議がないコンセンサスに到達できない場合は、多数決が -と呼ばれます。 また、TCによって行われた決定の大部分が +TCは、TCにエスカレートされた問題について「コンセンサスを求める」プロセスを使用します。グループは、TCメンバーの間に開かれた異議を持たない決議を見つけようとします。異議がないコンセンサスに到達できない場合は、多数決が +と呼ばれます。また、TCによって行われた決定の大部分が 合意形成プロセスを通じて行われ、投票は最後の手段としてのみ使用されることが期待されます。 解決には、 @@ -114,7 +111,7 @@ TCは、TCにエスカレートされた問題について「コンセンサス 会議では、その会議中に議題に関するすべての問題が解決されることは期待されておらず、プロジェクトキャプテン間で起こっている議論を 継続することを好むかもしれません。 -メンバーはいつでもTCに追加できます。 メンバーはいつでもTCに追加できます。 Any TC member can nominate another committer +メンバーはいつでもTCに追加できます。メンバーはいつでもTCに追加できます。 Any TC member can nominate another committer to the TC and the TC uses its standard consensus seeking process to evaluate whether or not to add this new member. TCは、最低3人のアクティブメンバーと最大10の で構成されます。 TCは、最低3人のアクティブメンバーと最大10の @@ -131,7 +128,7 @@ TCメンバーが過去12ヶ月以内に参加し、 連続したTCミーティングを見逃す必要があります。 Our goal is to increase participation, not punish people for any lack of participation, this guideline should be only be used as such (replace an inactive member with a new active one, for example). この -を満たしていないメンバーは辞退することが求められます。 この +を満たしていないメンバーは辞退することが求められます。この を満たしていないメンバーは辞退することが求められます。 TCメンバーがステップダウンしない場合、 ディスカッションリポジトリで問題を開き、それらを非アクティブ状態に移動できます。 により停止または削除されたTCメンバーは、非アクティブ状態に移動されます。 @@ -144,9 +141,8 @@ larger than the maximum of 10. 最大サイズで、 ### プロジェクトキャプテンズ Express TC では、 -組織内の個々のプロジェクト/リポジトリのキャプテンを指定できます。 これらのキャプテンは、技術的およびコミュニティの前線でレポの主要な -日々のメンテナーであることに責任があります。 -リポジトリのキャプテンは、リポジトリの所有権とパッケージの公開権を与えられます。 +組織内の個々のプロジェクト/リポジトリのキャプテンを指定できます。これらのキャプテンは、技術的およびコミュニティの前線でレポの主要な +日々のメンテナーであることに責任があります。リポジトリのキャプテンは、リポジトリの所有権とパッケージの公開権を与えられます。 When there are conflicts, especially on topics that effect the Express project at large, captains are responsible to raise it up to the TC and drive those conflicts to resolution. Captains are also responsible for making sure @@ -157,18 +153,17 @@ TCメンバーと同じように、レポキャプテンはコミッターの一 プロジェクトのキャプテンになるためには、候補者はリクエストの前に少なくとも6ヶ月間その プロジェクトに参加することが期待されます。 -がコードの貢献とトリアージの問題を助けてくれるはずです。 また、 +がコードの貢献とトリアージの問題を助けてくれるはずです。また、 がGitHubとNPMの両方のアカウントで2FAを有効にしている必要があります。 **同じ**リポジトリのTCメンバーまたは既存のキャプテンは、キャプテン役に別のコミッター -を指名することができます。 **同じ**リポジトリのTCメンバーまたは既存のキャプテンは、キャプテン役に別のコミッター +を指名することができます。**同じ**リポジトリのTCメンバーまたは既存のキャプテンは、キャプテン役に別のコミッター を指名することができます。 そのためには、この文書にPRを提出する必要があります。 **アクティブなプロジェクトキャプテン** セクション (並び替え順を維持しながら) をプロジェクト 名で更新します。 ノミネート者のGitHubハンドルとそのnpmユーザー名 (異なる場合)。 - レポは、仕事の範囲にとって意味のあるできるだけ多くのキャプテンを持つことができます。 -- TCメンバーまたは既存のリポジトリキャプテンは**同じプロジェクトにあります**。新しいキャプテンを指名できます。 - 他のプロジェクトからのレポキャプテンは、別のプロジェクトにキャプテンを指名してはいけません。 +- TCメンバーまたは既存のリポジトリキャプテンは**同じプロジェクトにあります**。新しいキャプテンを指名できます。他のプロジェクトからのレポキャプテンは、別のプロジェクトにキャプテンを指名してはいけません。 PRは、TCメンバーから少なくとも2件の承認が必要であり、コメントおよび/または反対のために を許可する2週間の保留期間が必要です。 PRがマージされると、TCメンバーはそれを @@ -191,11 +186,11 @@ PRは、TCメンバーから少なくとも2件の承認が必要であり、コ #### 例外 -個人的または専門的な理由により、誰でも積極的な参加から一時的な休暇を申請することができます。 このような場合、個人は関連するチームまたは技術委員会(TC)に通知する必要があります。 この間、非アクティブポリシーは一時停止され、個人は非アクティブとしてフラグ付けされません。 +個人的または専門的な理由により、誰でも積極的な参加から一時的な休暇を申請することができます。このような場合、個人は関連するチームまたは技術委員会(TC)に通知する必要があります。この間、非アクティブポリシーは一時停止され、個人は非アクティブとしてフラグ付けされません。 #### 非アクティブプロセス -- 誰かが非アクティブとみなされた場合、個人は過去の貢献を反映した名誉の役割に移行される可能性があります。 これが起こったことを彼らに知らせるために最善の努力がなされます。 彼らは再びアクティブになる準備ができたときに復帰を要求することができます。 +- 誰かが非アクティブとみなされた場合、個人は過去の貢献を反映した名誉の役割に移行される可能性があります。これが起こったことを彼らに知らせるために最善の努力がなされます。彼らは再びアクティブになる準備ができたときに復帰を要求することができます。 - 名誉の状態は、時間の経過とともにプロジェクトを成形した貢献者の明確な記録を保持するのに役立ちます。 #### Accountability @@ -261,7 +256,7 @@ Expressの将来のリリースである バグや追加したい機能の問題を作成します。 2. Create your own fork on GitHub, then checkout your fork. -3. ローカルコピーにコードを書きなさい。 必須ではありませんが、新しい課題ごとに +3. ローカルコピーにコードを書きなさい。必須ではありませんが、新しい課題ごとに ブランチを作成することは良い方法です。 4. テストスイートを実行するには、`npm install`、 を実行し、`npm test`を実行して依存関係をインストールします。 @@ -275,7 +270,7 @@ Expressの将来のリリースである ### 質問である問題 私たちは通常、あなたが書いているいくつかの -アプリに固有の漠然とした問題や質問を閉じます。 私たちは通常、あなたが書いているいくつかの +アプリに固有の漠然とした問題や質問を閉じます。私たちは通常、あなたが書いているいくつかの アプリに固有の漠然とした問題や質問を閉じます。 Please double check the docs and other references before being trigger happy with posting a question issue. @@ -346,8 +341,7 @@ You can find more information about our process in [this guide](https://github.c セキュリティ脆弱性を報告するには、 [GitHub Security Advisories](https://github.com/advisories)を使用します。 これにより、報告書の -の機密性を維持しながら修正に協力することができます。 -これにより、報告書の +の機密性を維持しながら修正に協力することができます。これにより、報告書の の機密性を維持しながら修正に協力することができます。 脆弱性 @@ -356,8 +350,7 @@ You can find more information about our process in [this guide](https://github.c 1. 影響を受けるリポジトリの **セキュリティ** タブを開きます。 2. **脆弱性を報告**をクリックし、指定された手順に従ってください。 -このプロセスは、Express エコシステム内のリポジトリに適用されます。 -このプロセスは、Express エコシステム内のリポジトリに適用されます。 +このプロセスは、Express エコシステム内のリポジトリに適用されます。このプロセスは、Express エコシステム内のリポジトリに適用されます。 If you are unsure whether a repository falls under this policy, feel free to reach out via email. @@ -367,7 +360,7 @@ feel free to reach out via email. タイムリーな対応を確実にするために、外部ソースにリンクしたりファイルを添付したりするのではなく、関連するすべての詳細をメール本文に直接記入してください。 -リードメンテナは48時間以内にあなたのメールを認識し、次のステップの概要を説明する最初の回答を提供します。 セキュリティチームは、進捗状況を更新し続け、追加の詳細を要求することがあります。 セキュリティチームは、進捗状況を更新し続け、追加の詳細を要求することがあります。 +リードメンテナは48時間以内にあなたのメールを認識し、次のステップの概要を説明する最初の回答を提供します。 セキュリティチームは、進捗状況を更新し続け、追加の詳細を要求することがあります。セキュリティチームは、進捗状況を更新し続け、追加の詳細を要求することがあります。 #### サードパーティーモジュール @@ -382,7 +375,7 @@ involving the following steps: - 問題を確認し、影響を受けるバージョンを確認します。 - 潜在的な同様の問題を見つけるために監査コード。 -- メンテナンス中のすべてのリリースの修正を準備します。 これらの修正は、npmにできるだけ早く +- メンテナンス中のすべてのリリースの修正を準備します。これらの修正は、npmにできるだけ早く リリースされます。 ### 本ポリシーに関するコメント @@ -392,8 +385,8 @@ involving the following steps: ### Express 脅威モデル -Express脅威モデルは、フレームワークがセキュリティ責任を考慮している限界を定義します。 信頼される要素(開発者、ランタイム環境、アプリケーションコードなど)と信頼されない要素(ネットワーク接続からのデータなど)を決定します。 信頼された要素から生じる問題は範囲外とみなされ、Express は信頼されていないデータを安全に処理する責任を負います。 信頼される要素(開発者、ランタイム環境、アプリケーションコードなど)と信頼されない要素(ネットワーク接続からのデータなど)を決定します。 信頼された要素から生じる問題は範囲外とみなされ、Express は信頼されていないデータを安全に処理する責任を負います。 +Express脅威モデルは、フレームワークがセキュリティ責任を考慮している限界を定義します。 信頼される要素(開発者、ランタイム環境、アプリケーションコードなど)と信頼されない要素(ネットワーク接続からのデータなど)を決定します。 信頼された要素から生じる問題は範囲外とみなされ、Express は信頼されていないデータを安全に処理する責任を負います。信頼される要素(開発者、ランタイム環境、アプリケーションコードなど)と信頼されない要素(ネットワーク接続からのデータなど)を決定します。信頼された要素から生じる問題は範囲外とみなされ、Express は信頼されていないデータを安全に処理する責任を負います。 -一般的に報告されている懸念の多くは、Expressのセキュリティ範囲外であり、アプリケーション開発者の責任です。 アンサニタイズされたユーザー入力からのプロトタイプ汚染、誤った設定された静的ファイルの提供、サードパーティーの依存関係での問題など。 +一般的に報告されている懸念の多くは、Expressのセキュリティ範囲外であり、アプリケーション開発者の責任です。アンサニタイズされたユーザー入力からのプロトタイプ汚染、誤った設定された静的ファイルの提供、サードパーティーの依存関係での問題など。 詳細については、[Express Threat Model](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)を参照してください。 diff --git a/src/content/pages/ja/resources/glossary.mdx b/src/content/pages/ja/resources/glossary.mdx index 0ffed9d49e..a7c1f58fff 100644 --- a/src/content/pages/ja/resources/glossary.mdx +++ b/src/content/pages/ja/resources/glossary.mdx @@ -7,15 +7,15 @@ import Alert from '@components/primitives/Alert/Alert.astro'; ## アプリケーション -一般に、特定の目的のために操作を実行するように設計された1つまたは複数のプログラム。 一般に、特定の目的のために操作を実行するように設計された1つまたは複数のプログラム。 Express のコンテキストでは、Node.js プラットフォームで実行される Express API を使用するプログラムがあります。 [app object](/api#express) も参照しているかもしれません。 Might also refer to an [app object](/api/express). +一般に、特定の目的のために操作を実行するように設計された1つまたは複数のプログラム。一般に、特定の目的のために操作を実行するように設計された1つまたは複数のプログラム。 Express のコンテキストでは、Node.js プラットフォームで実行される Express API を使用するプログラムがあります。 [app object](/api#express) も参照しているかもしれません。 Might also refer to an [app object](/api/express). ## API -アプリケーションプログラミングインターフェイス。 略語が最初に使用されたときにスペルアウトします。 略語が最初に使用されたときにスペルアウトします。 +アプリケーションプログラミングインターフェイス。 略語が最初に使用されたときにスペルアウトします。略語が最初に使用されたときにスペルアウトします。 ## エクスプレス -Node.jsアプリケーション用の高速で、意見が異なる、ミニマリストなWebフレームワーク。 一般的には「Express」は「Express.js」よりも好まれますが、後者は許容されます。 一般的には「Express」は「Express.js」よりも好まれますが、後者は許容されます。 +Node.jsアプリケーション用の高速で、意見が異なる、ミニマリストなWebフレームワーク。 一般的には「Express」は「Express.js」よりも好まれますが、後者は許容されます。一般的には「Express」は「Express.js」よりも好まれますが、後者は許容されます。 ## libuv @@ -31,7 +31,7 @@ Node.jsアプリケーション用の高速で、意見が異なる、ミニマ ## Node.js -スケーラブルなネットワークアプリケーションの構築に使用されるソフトウェアプラットフォーム。 スケーラブルなネットワークアプリケーションの構築に使用されるソフトウェアプラットフォーム。 Node.jsはJavaScriptをスクリプト言語として使用し、ノンブロッキングI/Oとシングルスレッドイベントループにより高いスループットを実現します。 [nodejs.org](https://nodejs.org/en/) を参照してください。 **使用上の注意**: 最初は、"Node.js"以降は"Node"です。 [nodejs.org](https://nodejs.org/en/) を参照してください。 **使用上の注意**: 最初は、"Node.js"以降は"Node"です。 +スケーラブルなネットワークアプリケーションの構築に使用されるソフトウェアプラットフォーム。スケーラブルなネットワークアプリケーションの構築に使用されるソフトウェアプラットフォーム。 Node.jsはJavaScriptをスクリプト言語として使用し、ノンブロッキングI/Oとシングルスレッドイベントループにより高いスループットを実現します。 [nodejs.org](https://nodejs.org/en/) を参照してください。 **使用上の注意**: 最初は、"Node.js"以降は"Node"です。 [nodejs.org](https://nodejs.org/en/) を参照してください。**使用上の注意**: 最初は、"Node.js"以降は"Node"です。 ## オープンソースのオープンソース @@ -50,11 +50,11 @@ HTTP リクエスト。 HTTPレスポンス。 サーバーはクライアント ## 応答 -HTTPレスポンス。 サーバーはクライアントに HTTP 応答メッセージを返します。 レスポンスには、リクエストに関する完了ステータス情報が含まれており、メッセージ本文に要求されたコンテンツが含まれている場合もあります。 +HTTPレスポンス。サーバーはクライアントに HTTP 応答メッセージを返します。レスポンスには、リクエストに関する完了ステータス情報が含まれており、メッセージ本文に要求されたコンテンツが含まれている場合もあります。 ## route -リソースを識別する URL の一部です。 リソースを識別する URL の一部です。 例えば、`http://foo.com/products/id`では、"/products/id"がルートです。 +リソースを識別する URL の一部です。リソースを識別する URL の一部です。 例えば、`http://foo.com/products/id`では、"/products/id"がルートです。 ## ルーター: diff --git a/src/content/pages/ja/resources/index.mdx b/src/content/pages/ja/resources/index.mdx index 4aed843d21..3aa190e92a 100644 --- a/src/content/pages/ja/resources/index.mdx +++ b/src/content/pages/ja/resources/index.mdx @@ -6,7 +6,7 @@ description: コミュニティ、ガイドライン、用語集、ユーティ import Card from '@components/primitives/Card/Card.astro'; import { CardList } from '@components/patterns'; -Express.jsエコシステムを学び、貢献し、接続するためのリソースを見つけましょう。 コミュニティに参加したい場合、ミドルウェアを探索したり、重要な概念を理解したりする場合でも、ここで必要なものが見つかります。 コミュニティに参加したい場合、ミドルウェアを探索したり、重要な概念を理解したりする場合でも、ここで必要なものが見つかります。 +Express.jsエコシステムを学び、貢献し、接続するためのリソースを見つけましょう。 コミュニティに参加したい場合、ミドルウェアを探索したり、重要な概念を理解したりする場合でも、ここで必要なものが見つかります。コミュニティに参加したい場合、ミドルウェアを探索したり、重要な概念を理解したりする場合でも、ここで必要なものが見つかります。 diff --git a/src/content/pages/ja/resources/middleware/body-parser.mdx b/src/content/pages/ja/resources/middleware/body-parser.mdx index ba96351dfd..cc54496fd7 100644 --- a/src/content/pages/ja/resources/middleware/body-parser.mdx +++ b/src/content/pages/ja/resources/middleware/body-parser.mdx @@ -27,7 +27,7 @@ and `toString` may not be a function and instead a string or other user input. [Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction). *これは複合体であり、通常は -大きな性質のため、マルチパートbody*を扱いません。 マルチパートボディの場合、以下の +大きな性質のため、マルチパートbody*を扱いません。マルチパートボディの場合、以下の モジュールに興味があるかもしれません。 - [busboy](https://www.npmjs.com/package/busboy#readme) と @@ -44,6 +44,10 @@ and `toString` may not be a function and instead a string or other user input. - [Text body parser](#bodyparsertextoptions) - [URL-encoded form body parser](#bodyparserurlencodedoptions) +All parsers support automatic inflation of `gzip`, `br` (brotli), `deflate` +and `zstd` encodings. `zstd` is available in Node.js `^22.15.0` and +`>=23.8.0`. + あなたが興味を持っているかもしれない他のボディパーサ: - [body](https://www.npmjs.com/package/body#readme) @@ -84,9 +88,8 @@ the `Content-Type` request header matches the `type` option. ### bodyParser.json([options]) Returns middleware that only parses `json` and only looks at requests where -the `Content-Type` header matches the `type` option. このパーサーは -Unicode エンコーディングを受け付け、`gzip`, -`br`, `deflate` エンコーディングの自動インフレーションをサポートしています。 +the `Content-Type` header matches the `type` option. This parser accepts any +Unicode encoding of the body. ミドルウェアの後に `request` オブジェクトに解析されたデータを含む新しい`body` オブジェクトが追加されました。 @@ -99,20 +102,20 @@ the following keys: ##### defaultCharset リクエストの `Content-Type` ヘッダーに文字セットが -指定されていない場合、json コンテンツのデフォルト文字セットを指定します。 デフォルトは `utf-8` です。 +指定されていない場合、json コンテンツのデフォルト文字セットを指定します。デフォルトは `utf-8` です。 ##### 膨らませ `true` に設定されている場合、デフレートされた(圧縮された)ボディは膨らまれます。 -`false` の場合、デフレートされたボディは拒否されます。 デフォルトは `true` です。 +`false` の場合、デフレートされたボディは拒否されます。デフォルトは `true` です。 ##### 制限 -リクエストボディの最大サイズを制御します。 これが数値の場合、値 -はバイト数を指定します。 文字列であれば、値は[bytes](https://www.npmjs.com/package/bytes) ライブラリに渡され、解析します。 デフォルト +リクエストボディの最大サイズを制御します。これが数値の場合、値 +はバイト数を指定します。 文字列であれば、値は[bytes](https://www.npmjs.com/package/bytes) ライブラリに渡され、解析します。デフォルト は `'100kb'` です。 -> 可能な限り高い制限を設定し、可能な限りデフォルト値を使用しないことをお勧めします。 より大きなペイロードを許可すると、デコードと変換に必要なリソースのため、メモリ使用量が増加します。 より多くのデータが処理されるにつれて応答時間が長くなることもあります 「非常に高い」とは、例えば5MB以上のペイロードなど、デフォルトよりも高い値を意味しますが、既にこれらのリスクを導入し始めています。 デフォルトの制限では、これらの問題は発生しません。 +> 可能な限り高い制限を設定し、可能な限りデフォルト値を使用しないことをお勧めします。より大きなペイロードを許可すると、デコードと変換に必要なリソースのため、メモリ使用量が増加します。 より多くのデータが処理されるにつれて応答時間が長くなることもあります「非常に高い」とは、例えば5MB以上のペイロードなど、デフォルトよりも高い値を意味しますが、既にこれらのリスクを導入し始めています。デフォルトの制限では、これらの問題は発生しません。 ##### reviver @@ -128,29 +131,27 @@ accept anything `JSON.parse` accepts. デフォルトは `true` です。 ##### タイプ `type` オプションは、ミドルウェアが -解析するメディアタイプを決定するために使用されます。 このオプションは文字列、文字列の配列、または関数です。 If not a +解析するメディアタイプを決定するために使用されます。このオプションは文字列、文字列の配列、または関数です。 If not a function, `type` option is passed directly to the [type-is](https://www.npmjs.com/package/type-is#readme) library and this can be an extension name (like `json`), a mime type (like `application/json`), or a mime type with a wildcard (like `*/*` or `*/json`). 関数の場合、`type` オプションは`fn(req)`と呼ばれ、リクエストは真の -値を返した場合に解析されます。 デフォルトは `application/json` です。 +値を返した場合に解析されます。デフォルトは `application/json` です。 ##### 確認する `verify` オプションを指定すると、`verify(req, res, buf, encoding)`と呼ばれます。 で、 `buf` は生のリクエストボディの `Buffer` で、 `encoding` はリクエストの -エンコーディングです。 エラーを投げることで解析を中止することができます。 +エンコーディングです。エラーを投げることで解析を中止することができます。 ### bodyParser.raw([options]) 全ての本文を`Buffer`として解析し、`Content-Type`ヘッダーが`type`オプションにマッチする -リクエストのみを参照するミドルウェアを返します。 この -パーサは、 `gzip` 、 `br` (brotli) 、 `deflate` -エンコーディングの自動インフレーションをサポートします。 +リクエストのみを参照するミドルウェアを返します。 ミドルウェアの後に `request` -オブジェクトに解析されたデータを含む新しい`body` オブジェクトが追加されました。 これは本文の `Buffer` オブジェクト +オブジェクトに解析されたデータを含む新しい`body` オブジェクトが追加されました。これは本文の `Buffer` オブジェクト になります。 #### オプション @@ -161,44 +162,42 @@ the following keys: ##### 膨らませ `true` に設定されている場合、デフレートされた(圧縮された)ボディは膨らまれます。 -`false` の場合、デフレートされたボディは拒否されます。 デフォルトは `true` です。 +`false` の場合、デフレートされたボディは拒否されます。デフォルトは `true` です。 ##### 制限 -リクエストボディの最大サイズを制御します。 これが数値の場合、値 -はバイト数を指定します。 文字列であれば、値は[bytes](https://www.npmjs.com/package/bytes) ライブラリに渡され、解析します。 デフォルト +リクエストボディの最大サイズを制御します。これが数値の場合、値 +はバイト数を指定します。 文字列であれば、値は[bytes](https://www.npmjs.com/package/bytes) ライブラリに渡され、解析します。デフォルト は `'100kb'` です。 -> 可能な限り高い制限を設定し、可能な限りデフォルト値を使用しないことをお勧めします。 より大きなペイロードを許可すると、デコードと変換に必要なリソースのため、メモリ使用量が増加します。 より多くのデータが処理されるにつれて応答時間が長くなることもあります 「非常に高い」とは、例えば5MB以上のペイロードなど、デフォルトよりも高い値を意味しますが、既にこれらのリスクを導入し始めています。 デフォルトの制限では、これらの問題は発生しません。 +> 可能な限り高い制限を設定し、可能な限りデフォルト値を使用しないことをお勧めします。より大きなペイロードを許可すると、デコードと変換に必要なリソースのため、メモリ使用量が増加します。 より多くのデータが処理されるにつれて応答時間が長くなることもあります「非常に高い」とは、例えば5MB以上のペイロードなど、デフォルトよりも高い値を意味しますが、既にこれらのリスクを導入し始めています。デフォルトの制限では、これらの問題は発生しません。 ##### タイプ `type` オプションは、ミドルウェアが -解析するメディアタイプを決定するために使用されます。 このオプションは文字列、文字列の配列、または関数です。 +解析するメディアタイプを決定するために使用されます。このオプションは文字列、文字列の配列、または関数です。 If not a function, `type` option is passed directly to the [type-is](https://www.npmjs.com/package/type-is#readme) library and this can be an extension name (like `bin`), a mime type (like `application/octet-stream`), or a mime type with a wildcard (like `*/*` or `application/*`). 関数の場合、`type` オプションは `fn(req)` -と呼ばれ、リクエストは真の値を返す場合に解析されます。 デフォルトは +と呼ばれ、リクエストは真の値を返す場合に解析されます。デフォルトは `application/octet-stream` です。 ##### 確認する `verify` オプションを指定すると、`verify(req, res, buf, encoding)`と呼ばれます。 で、 `buf` は生のリクエストボディの `Buffer` で、 `encoding` はリクエストの -エンコーディングです。 エラーを投げることで解析を中止することができます。 +エンコーディングです。エラーを投げることで解析を中止することができます。 ### bodyParser.text([options]) 全ての本文を文字列として解析し、`Content-Type`ヘッダーが`type`オプションにマッチする -リクエストのみを参照するミドルウェアを返します。 この -パーサは、 `gzip` 、 `br` (brotli) 、 `deflate` -エンコーディングの自動インフレーションをサポートします。 +リクエストのみを参照するミドルウェアを返します。 -ミドルウェアの後に `request` -オブジェクトに解析されたデータを含む新しい`body` 文字列が追加されます。 これは、 -本体の文字列になります。 +A new `body` string containing the parsed data is populated on the `request` +object after the middleware (i.e. `req.body`). This will be a string of the +body. #### オプション @@ -207,45 +206,44 @@ the following keys: ##### defaultCharset -リクエストの `Content-Type` ヘッダーに文字セットが -指定されていない場合、テキストコンテンツのデフォルト文字セットを指定します。 デフォルトは `utf-8` です。 +Specify the default character set for the text content if the charset is not +specified in the `Content-Type` header of the request. デフォルトは `utf-8` です。 ##### 膨らませ `true` に設定されている場合、デフレートされた(圧縮された)ボディは膨らまれます。 -`false` の場合、デフレートされたボディは拒否されます。 デフォルトは `true` です。 +`false` の場合、デフレートされたボディは拒否されます。デフォルトは `true` です。 ##### 制限 -リクエストボディの最大サイズを制御します。 これが数値の場合、値 -はバイト数を指定します。 文字列であれば、値は[bytes](https://www.npmjs.com/package/bytes) ライブラリに渡され、解析します。 デフォルト +リクエストボディの最大サイズを制御します。これが数値の場合、値 +はバイト数を指定します。 文字列であれば、値は[bytes](https://www.npmjs.com/package/bytes) ライブラリに渡され、解析します。デフォルト は `'100kb'` です。 -> 可能な限り高い制限を設定し、可能な限りデフォルト値を使用しないことをお勧めします。 より大きなペイロードを許可すると、デコードと変換に必要なリソースのため、メモリ使用量が増加します。 より多くのデータが処理されるにつれて応答時間が長くなることもあります 「非常に高い」とは、例えば5MB以上のペイロードなど、デフォルトよりも高い値を意味しますが、既にこれらのリスクを導入し始めています。 デフォルトの制限では、これらの問題は発生しません。 +> 可能な限り高い制限を設定し、可能な限りデフォルト値を使用しないことをお勧めします。より大きなペイロードを許可すると、デコードと変換に必要なリソースのため、メモリ使用量が増加します。 より多くのデータが処理されるにつれて応答時間が長くなることもあります「非常に高い」とは、例えば5MB以上のペイロードなど、デフォルトよりも高い値を意味しますが、既にこれらのリスクを導入し始めています。デフォルトの制限では、これらの問題は発生しません。 ##### タイプ `type` オプションは、ミドルウェアが -解析するメディアタイプを決定するために使用されます。 このオプションは文字列、文字列の配列、または関数です。 If not +解析するメディアタイプを決定するために使用されます。このオプションは文字列、文字列の配列、または関数です。 If not a function, `type` option is passed directly to the [type-is](https://www.npmjs.com/package/type-is#readme) library and this can be an extension name (like `txt`), a mime type (like `text/plain`), or a mime -type with a wildcard (like `*/*` or `text/*`). 関数の場合、`type` -オプションは`fn(req)`と呼ばれ、 -truthy値を返す場合はリクエストが解析されます。 デフォルトは `text/plain` です。 +type with a wildcard (like `*/*` or `text/*`). If a function, the `type` +option is called as `fn(req)` and the request is parsed if it returns a +truthy value. Defaults to `text/plain`. ##### 確認する `verify` オプションを指定すると、`verify(req, res, buf, encoding)`と呼ばれます。 で、 `buf` は生のリクエストボディの `Buffer` で、 `encoding` はリクエストの -エンコーディングです。 エラーを投げることで解析を中止することができます。 +エンコーディングです。エラーを投げることで解析を中止することができます。 ### bodyParser.urlencoded([options]) -`urlencoded` ボディのみを解析し、`Content-Type` ヘッダーが `type` オプションに一致する場合の -リクエストのみを参照するミドルウェアを返します。 この -パーサは、ボディのUTF-8とISO-8859-1エンコーディングのみを受け付け、`gzip`、`br`(brotli)および`deflate`エンコーディングの -自動インフレーションをサポートします。 +Returns middleware that only parses `urlencoded` bodies and only looks at +requests where the `Content-Type` header matches the `type` option. This +parser accepts only UTF-8 and ISO-8859-1 encodings of the body. ミドルウェアの後に `request` オブジェクトに解析されたデータを含む新しい`body` オブジェクトが追加されました。 This object will contain @@ -257,179 +255,179 @@ key-value pairs, where the value can be a string or array (when `extended` is The `urlencoded` function takes an optional `options` object that may contain any of the following keys: -##### 拡張 +##### extended -「拡張された」構文により、リッチオブジェクトや配列を -URLエンコードされた形式にエンコードすることができ、JSONに似たURLエンコードを行うことができます。 -の詳細については、qs -libraryを参照してください。 +The "extended" syntax allows for rich objects and arrays to be encoded into the +URL-encoded format, allowing for a JSON-like experience with URL-encoded. For +more information, please see the qs +library. -デフォルトは `false` です。 +Defaults to `false`. ##### 膨らませ `true` に設定されている場合、デフレートされた(圧縮された)ボディは膨らまれます。 -`false` の場合、デフレートされたボディは拒否されます。 デフォルトは `true` です。 +`false` の場合、デフレートされたボディは拒否されます。デフォルトは `true` です。 ##### 制限 -リクエストボディの最大サイズを制御します。 これが数値の場合、値 -はバイト数を指定します。 文字列であれば、値は[bytes](https://www.npmjs.com/package/bytes) ライブラリに渡され、解析します。 デフォルト +リクエストボディの最大サイズを制御します。これが数値の場合、値 +はバイト数を指定します。 文字列であれば、値は[bytes](https://www.npmjs.com/package/bytes) ライブラリに渡され、解析します。デフォルト は `'100kb'` です。 -> 可能な限り高い制限を設定し、可能な限りデフォルト値を使用しないことをお勧めします。 より大きなペイロードを許可すると、デコードと変換に必要なリソースのため、メモリ使用量が増加します。 より多くのデータが処理されるにつれて応答時間が長くなることもあります 「非常に高い」とは、例えば5MB以上のペイロードなど、デフォルトよりも高い値を意味しますが、既にこれらのリスクを導入し始めています。 デフォルトの制限では、これらの問題は発生しません。 +> 可能な限り高い制限を設定し、可能な限りデフォルト値を使用しないことをお勧めします。より大きなペイロードを許可すると、デコードと変換に必要なリソースのため、メモリ使用量が増加します。 より多くのデータが処理されるにつれて応答時間が長くなることもあります「非常に高い」とは、例えば5MB以上のペイロードなど、デフォルトよりも高い値を意味しますが、既にこれらのリスクを導入し始めています。デフォルトの制限では、これらの問題は発生しません。 -##### パラメータ制限 +##### parameterLimit -`parameterLimit` オプションは、URLでエンコードされたデータ内で -が許可されるパラメータの最大数を制御します。 リクエストにこの値よりも多くのパラメータ -が含まれている場合、413がクライアントに返されます。 デフォルトは `1000` です。 +The `parameterLimit` option controls the maximum number of parameters that +are allowed in the URL-encoded data. If a request contains more parameters +than this value, a 413 will be returned to the client. Defaults to `1000`. ##### タイプ `type` オプションは、ミドルウェアが -解析するメディアタイプを決定するために使用されます。 このオプションは文字列、文字列の配列、または関数です。 If not +解析するメディアタイプを決定するために使用されます。このオプションは文字列、文字列の配列、または関数です。 If not a function, `type` option is passed directly to the [type-is](https://www.npmjs.com/package/type-is#readme) library and this can be an extension name (like `urlencoded`), a mime type (like `application/x-www-form-urlencoded`), or a mime type with a wildcard (like -`*/x-www-form-urlencoded`). 関数の場合、`type`オプションは -`fn(req)`と呼ばれ、リクエストは真の値を返した場合に解析されます。 デフォルト -は `application/x-www-form-urlencoded` です。 +`*/x-www-form-urlencoded`). If a function, the `type` option is called as +`fn(req)` and the request is parsed if it returns a truthy value. Defaults +to `application/x-www-form-urlencoded`. ##### 確認する `verify` オプションを指定すると、`verify(req, res, buf, encoding)`と呼ばれます。 で、 `buf` は生のリクエストボディの `Buffer` で、 `encoding` はリクエストの -エンコーディングです。 エラーを投げることで解析を中止することができます。 +エンコーディングです。エラーを投げることで解析を中止することができます。 ##### defaultCharset -コンテンツ型で指定されていない場合、パースするデフォルトの文字セット。 Must be +The default charset to parse as, if not specified in content-type. Must be either `utf-8` or `iso-8859-1`. デフォルトは `utf-8` です。 ##### charsetSentinel -`utf8`パラメータの値を文字セット -セレクタとして優先するかどうか。 It requires the form to contain a parameter named `utf8` with a value -of `✓`. デフォルトは `false` です。 +Whether to let the value of the `utf8` parameter take precedence as the charset +selector. It requires the form to contain a parameter named `utf8` with a value +of `✓`. Defaults to `false`. -##### NumericEntities +##### interpretNumericEntities Whether to decode numeric entities such as `☺` when parsing an iso-8859-1 -form. デフォルトは `false` です。 +form. Defaults to `false`. -##### 深さ +##### depth -`depth` オプションは、`extended` が `true` の場合、`qs` ライブラリの最大深度を設定するために使用されます。 これにより、パースされたキーの量を制限でき、特定のタイプの乱用を防ぐのに役立ちます。 デフォルトは `32` です。 この値をできるだけ低く保つことをお勧めします。 +The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible. -## エラー +## Errors -このモジュールで提供されるミドルウェアは、 -[`http-errors` モジュール](https://www.npmjs.com/package/http-errors) を使用してエラーを生成します。 The errors +The middlewares provided by this module create errors using the +[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors will typically have a `status`/`statusCode` property that contains the suggested HTTP response code, an `expose` property to determine if the `message` property should be displayed to the client, a `type` property to determine the type of error without matching against the `message`, and a `body` property containing the read body, if available. -以下は一般的なエラーですが、さまざまな理由で -を介してエラーが発生する可能性があります。 +The following are the common errors created, though any error can come through +for various reasons. -### コンテンツエンコーディングはサポートされていません +### content encoding unsupported -このエラーは、 -にエンコーディングが含まれていて、"inflation" オプションが `false` に設定されている `Content-Encoding` ヘッダーがリクエストに含まれていた場合に発生します。 The +This error will occur when the request had a `Content-Encoding` header that +contained an encoding but the "inflation" option was set to `false`. The `status` property is set to `415`, the `type` property is set to `'encoding.unsupported'`, and the `charset` property will be set to the encoding that is unsupported. -### エンティティの解析に失敗しました +### entity parse failed This error will occur when the request contained an entity that could not be parsed by the middleware. The `status` property is set to `400`, the `type` property is set to `'entity.parse.failed'`, and the `body` property is set to the entity value that failed parsing. -### エンティティの検証に失敗しました +### entity verify failed -このエラーは、定義された `verify` オプションで -失敗した検証に失敗したエンティティがリクエストに含まれている場合に発生します。 The `status` property is +This error will occur when the request contained an entity that could not be +verified by the defined `verify` option. The `status` property is set to `403`, the `type` property is set to `'entity.verify.failed'`, and the `body` property is set to the entity value that failed verification. -### リクエストは中止されました +### request aborted -このエラーは、 -本文を読み込む前に、リクエストがクライアントによって中止された場合に発生します。 The `received` property will be set to the number of -bytes before the request was aborted and the `expected` property is -set to the number of expected bytes. `status` プロパティは `400` -に設定され、`type` プロパティは `'request.aborted'` に設定されます。 +This error will occur when the request is aborted by the client before reading +the body has finished. The `received` property will be set to the number of +bytes received before the request was aborted and the `expected` property is +set to the number of expected bytes. The `status` property is set to `400` +and `type` property is set to `'request.aborted'`. -### 要求エンティティが大きすぎます +### request entity too large -このエラーは、リクエストボディのサイズが "limit" -オプションより大きい場合に発生します。 `limit` プロパティはバイト制限に設定され、`length` -プロパティはリクエスト本体の長さに設定されます。 `status` プロパティは -に設定されており、`type` プロパティは `entity.too.large'` に設定されています。 +This error will occur when the request body's size is larger than the "limit" +option. The `limit` property will be set to the byte limit and the `length` +property will be set to the request body's length. The `status` property is +set to `413` and the `type` property is set to `'entity.too.large'`. -### 要求サイズがコンテンツの長さと一致しません +### request size did not match content length -このエラーは、リクエストの長さが `Content-Length` ヘッダの -の長さと一致しなかった場合に発生します。 これは通常、リクエストが不正な形式になったときに発生します。 -通常、バイトではなく -文字に基づいて `Content-Length` ヘッダーが計算されたときです。 `status`プロパティは`400`に、`type`プロパティ -は`'request.size.invalid'`に設定されています。 +This error will occur when the request's length did not match the length from +the `Content-Length` header. This typically occurs when the request is malformed, +typically when the `Content-Length` header was calculated based on characters +instead of bytes. The `status` property is set to `400` and the `type` property +is set to `'request.size.invalid'`. -### ストリームのエンコーディングを設定できません +### stream encoding should not be set -このエラーは、このミドルウェアの -より前に `req.setEncoding` メソッドと呼ばれるものが発生します。 This module operates directly on bytes only and you cannot -call `req.setEncoding` when using this module. `status` プロパティは -`500` に設定され、`type` プロパティは `'stream.encoding.set'` に設定されます。 +This error will occur when something called the `req.setEncoding` method prior +to this middleware. This module operates directly on bytes only and you cannot +call `req.setEncoding` when using this module. The `status` property is set to +`500` and the `type` property is set to `'stream.encoding.set'`. -### ストリームが読み込めません +### stream is not readable -このエラーは、このミドルウェア -が読み込みを試みたときにリクエストが読み取れなくなったときに発生します。 これは通常、このモジュールがリクエスト本文を読み込んだ -ミドルウェア以外のものを意味し、ミドルウェアも -同じリクエストを読み込むように設定されています。 `status` プロパティは `500` に設定され、`type` -プロパティは `'stream.not.readable'` に設定されます。 +This error will occur when the request is no longer readable when this middleware +attempts to read it. This typically means something other than a middleware from +this module read the request body already and the middleware was also configured to +read the same request. The `status` property is set to `500` and the `type` +property is set to `'stream.not.readable'`. -### パラメータが多すぎます +### too many parameters -このエラーは、リクエストのコンテンツが `urlencoded` parserの設定された -`parameterLimit` を超えた場合に発生します。 `status` プロパティは -`413` に設定され、`type` プロパティは `'parameters.too.many'` に設定されます。 +This error will occur when the content of the request exceeds the configured +`parameterLimit` for the `urlencoded` parser. The `status` property is set to +`413` and the `type` property is set to `'parameters.too.many'`. -### 未サポートの文字セット "BOGUS" +### unsupported charset "BOGUS" This error will occur when the request had a charset parameter in the `Content-Type` header, but the `iconv-lite` module does not support it OR the -parser does not support it. charset は `charset` プロパティと同様に -メッセージにも含まれています。 The `status` property is set to `415`, the +parser does not support it. The charset is contained in the message as well +as in the `charset` property. The `status` property is set to `415`, the `type` property is set to `'charset.unsupported'`, and the `charset` property is set to the charset that is unsupported. -### サポートされていないコンテンツエンコーディング"bogus" +### unsupported content encoding "bogus" -このエラーは、リクエストに -サポートされていないエンコーディングが含まれている `Content-Encoding` ヘッダーがある場合に発生します。 エンコーディングは -メッセージと `encoding` プロパティに含まれます。 The `status` property is set to `415`, +This error will occur when the request had a `Content-Encoding` header that +contained an unsupported encoding. The encoding is contained in the message +as well as in the `encoding` property. The `status` property is set to `415`, the `type` property is set to `'encoding.unsupported'`, and the `encoding` property is set to the encoding that is unsupported. -### 入力が深さを超えました +### The input exceeded the depth -このエラーは、`extended` プロパティが `true` に設定されている `bodyParser.urlencoded` を使用し、入力が設定された `depth` オプションを超えた場合に発生します。 `status` プロパティは `400` に設定されています。 `depth`オプションを確認し、より高い値が必要かどうかを評価することをお勧めします。 `depth`オプションが`32`(デフォルト値)に設定されている場合、エラーはスローされません。 +This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown. ## 例 -### Express/Connect トップレベルジェネリック +### Express/Connect top-level generic -この例では、ジェネリックな JSON と URL エンコードされたパーサを -トップレベルのミドルウェアとして追加し、すべてのリクエストの本文をパースします。 -これは最も単純な設定です。 +This example demonstrates adding a generic JSON and URL-encoded parser as a +top-level middleware, which will parse the bodies of all incoming requests. +This is the simplest setup. ```js const express = require('express'); @@ -450,11 +448,11 @@ app.use(function (req, res) { }); ``` -### エクスプレスルート固有のルート +### Express route-specific -この例では、 -が必要とするルートにボディパーサを追加することを示します。 一般に、これは -Expressでbody-parserを使用するために最も推奨される方法です。 +This example demonstrates adding body parsers specifically to the routes that +need them. In general, this is the most recommended way to use body-parser with +Express. ```js const express = require('express'); @@ -481,10 +479,10 @@ app.post('/api/users', jsonParser, function (req, res) { }); ``` -### Parserの許容タイプの変更 +### Change accepted type for parsers -全てのパーサーは、ミドルウェアが解析する -`Content-Type` を変更することができる`type` オプションを受け付けます。 +All the parsers accept a `type` option which allows you to change the +`Content-Type` that the middleware will parse. ```js const express = require('express'); diff --git a/src/content/pages/ja/resources/middleware/compression.mdx b/src/content/pages/ja/resources/middleware/compression.mdx index 826b3c6cc1..bfaf74ff67 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 ミドルウェア --- @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -21,13 +21,13 @@ Node.js compression ミドルウェア。 - gzip - br (brotli) -**注意** BrotliはNode.jsのバージョンv11.7.0とv10.16.0以降のみサポートされています。 +**Note** Brotli is available in all currently supported Node.js LTS versions (v18+). ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは -[`npm install` コマンド](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは +[`npm install` コマンド](https://docs.npmjs.com/downloading-and-installing-packages-locally): @@ -47,7 +47,7 @@ var compression = require('compression'); ### compression([options]) -`options` を使用して圧縮ミドルウェアを返します。 ミドルウェア +`options` を使用して圧縮ミドルウェアを返します。ミドルウェア は、指定された `options` に基づいて、 ミドルウェアを横断するすべてのリクエストに対してレスポンスボディを圧縮しようとします。 @@ -87,8 +87,8 @@ the response. Type: `Number`
Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1` -応答に適用するzlib圧縮のレベル。 より高いレベルの場合、 -の圧縮が向上しますが、完了までに時間がかかります。 レベルが低い場合、 +応答に適用するzlib圧縮のレベル。より高いレベルの場合、 +の圧縮が向上しますが、完了までに時間がかかります。レベルが低い場合、 は圧縮が少なくなりますが、はるかに速くなります。 This is an integer in the range of `0` (no compression) to `9` (maximum @@ -126,29 +126,27 @@ Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8` 型: `Object` -Brotliを設定するためのオプションを指定します。 利用可能なオプションの一覧については、[Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions)を参照してください。 +Brotliを設定するためのオプションを指定します。利用可能なオプションの一覧については、[Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions)を参照してください。 ##### 戦略 Type: `Number`
Default: `zlib.constants.Z_DEFAULT_STRATEGY` -これは圧縮アルゴリズムのチューニングに使用されます。 この値は、 +これは圧縮アルゴリズムのチューニングに使用されます。この値は、 圧縮比にのみ影響し、 が適切に設定されていなくても、圧縮出力の正確性には影響しません。 - `zlib.constants.Z_DEFAULT_STRATEGY` 通常のデータに使用します。 -- `zlib.constants.Z_FILTERED` フィルター (または予測子) によって生成されたデータに使用します。 - フィルタリングされたデータは、多少ランダムな - 分布を持つ小さな値で構成されています。 この場合、圧縮アルゴリズムは - に調整され、圧縮が良くなります。 この効果は、より多くのハフマンのコーディングと +- `zlib.constants.Z_FILTERED` フィルター (または予測子) によって生成されたデータに使用します。フィルタリングされたデータは、多少ランダムな + 分布を持つ小さな値で構成されています。この場合、圧縮アルゴリズムは + に調整され、圧縮が良くなります。この効果は、より多くのハフマンのコーディングと より小さい文字列のマッチングを強制することです; `zlib.constants.Z_DEFAULT_STRATEGY` と `zlib.constants.Z_HUFFMAN_ONLY` の中間です。 - `zlib.constants.Z_FIXED` 動的ハフマンコードの使用を防ぐために使用します。 を使用すると、特殊なアプリケーションのデコーダが簡単になります。 - `zlib.constants.Z_HUFFMAN_ONLY` Huffman エンコーディングのみを強制するために使用します (文字列が一致しません)。 -- `zlib.constants.Z_RLE` 距離を1つに一致させるのに使用します(実行長エンコーディング)。 - これは `zlib.constants.Z_HUFFMAN_ONLY` とほぼ同じ速さで設計されていますが、PNG画像の場合は +- `zlib.constants.Z_RLE` 距離を1つに一致させるのに使用します(実行長エンコーディング)。これは `zlib.constants.Z_HUFFMAN_ONLY` とほぼ同じ速さで設計されていますが、PNG画像の場合は より良い圧縮を行うように設計されています。 上のリストの**Note** `zlib`は`zlib = require('zlib')`のものです。 @@ -184,7 +182,7 @@ Default: `identity` #### .filter -デフォルトの `filter` 関数。 これは、デフォルト関数の拡張であるカスタム フィルター +デフォルトの `filter` 関数。これは、デフォルト関数の拡張であるカスタム フィルター 関数を構築するために使用されます。 ```js @@ -216,7 +214,7 @@ function shouldCompress(req, res) { ### エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス|エクスプレス| 式でこのモジュールを使用する場合は、単純に `app.use` でモジュールを -ハイにします。 ミドルウェアを通過するリクエストは圧縮されます。 +ハイにします。ミドルウェアを通過するリクエストは圧縮されます。 ```js var compression = require('compression'); @@ -263,8 +261,8 @@ server.listen(3000, () => { ### サーバー送信イベント 圧縮の性質上、このモジュールはサーバ送信イベントの -ボックスからは動作しません。 コンテンツを圧縮するには、良好な圧縮を得るために出力ウィンドウを -バッファリングする必要があります。 通常、サーバー送信の +ボックスからは動作しません。コンテンツを圧縮するには、良好な圧縮を得るために出力ウィンドウを +バッファリングする必要があります。通常、サーバー送信の イベントを使用する場合、クライアントに到達する必要のある特定のデータブロックがあります。 に書き込まれたデータが実際にクライアントに送られる必要がある場合は、`res.flush()`を呼び出すことでこれを実現できます。 @@ -303,7 +301,7 @@ Express.jsプロジェクトは、すべての建設的な貢献を歓迎しま from code for bug fixes and enhancements, to additions and fixes to documentation, additional tests, triaging incoming pull requests and issues, and more! -See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing. +See the [Contributing Guide](https://github.com/expressjs/.github/blob/HEAD/CONTRIBUTING.md) for more technical details on contributing. ## ライセンス diff --git a/src/content/pages/ja/resources/middleware/cookie-parser.mdx b/src/content/pages/ja/resources/middleware/cookie-parser.mdx index eadff9216a..d5eb4313c0 100644 --- a/src/content/pages/ja/resources/middleware/cookie-parser.mdx +++ b/src/content/pages/ja/resources/middleware/cookie-parser.mdx @@ -41,11 +41,11 @@ var cookieParser = require('cookie-parser'); 与えられた `secret` と `options` を使用して、新しいクッキーパーサミドルウェア関数を作成します。 -- `secret` cookieへの署名に使用される文字列または配列。 これはオプションで、 - が指定されていない場合、署名されたクッキーを解析しません。 文字列が与えられた場合、この - がシークレットとして使用されます。 配列が指定された場合、 +- `secret` cookieへの署名に使用される文字列または配列。これはオプションで、 + が指定されていない場合、署名されたクッキーを解析しません。文字列が与えられた場合、この + がシークレットとして使用されます。配列が指定された場合、 シークレットごとにクッキーの署名を解除しようとします。 -- `options` 2 番目のオプションとして `cookie.parse` に渡されるオブジェクト。 詳細は +- `options` 2 番目のオプションとして `cookie.parse` に渡されるオブジェクト。詳細は [cookie](https://www.npmjs.org/package/cookie) を参照してください。 - `decode` クッキーの値をデコードする関数 @@ -55,14 +55,13 @@ the property `req.signedCookies`. これらのプロパティは、クッキー クッキー名の名前値のペアです。 `secret` が提供されると、このモジュールは署名を解除して署名された Cookie -の値を検証し、それらの値のペアを `req.cookies` から `req.signedCookies` に移動します。 -署名されたクッキーは、`:`の前に値が付いたクッキーです。 署名済みクッキー +の値を検証し、それらの値のペアを `req.cookies` から `req.signedCookies` に移動します。署名されたクッキーは、`:`の前に値が付いたクッキーです。署名済みクッキー 失敗する署名検証は、改ざんされた 値の代わりに `false` になります。 -さらに、このモジュールは特別な「JSON Cookie」をサポートしています。 これらは -の前に`j:`が付いているクッキーです。 これらの値に遭遇すると、値は -が JSON.parse\` の結果として公開されます。 解析に失敗した場合、元の値は +さらに、このモジュールは特別な「JSON Cookie」をサポートしています。これらは +の前に`j:`が付いているクッキーです。これらの値に遭遇すると、値は +が JSON.parse\` の結果として公開されます。解析に失敗した場合、元の値は のままになります。 ### cookieParser.JSONCookie(str) @@ -73,28 +72,28 @@ JSON クッキーとしてクッキーの値を解析します。 JSONクッキ ### cookieParser.JSONCookies(cookies) オブジェクトが与えられると、キーに対して反復処理を行い、各 -値に対して `JSONCookie` を呼び出し、元の値をパースされた値に置き換えます。 これは渡された +値に対して `JSONCookie` を呼び出し、元の値をパースされた値に置き換えます。これは渡された 同じオブジェクトを返します。 ### cookieParser.signedCookie(str, secret) -クッキーの値を署名されたクッキーとして解析します。 これは、署名されたCookieで署名が有効であった場合、解析された未署名の -値を返します。 値が -であった場合、元の値が返されます。 値が署名されたが、 +クッキーの値を署名されたクッキーとして解析します。これは、署名されたCookieで署名が有効であった場合、解析された未署名の +値を返します。値が +であった場合、元の値が返されます。値が署名されたが、 署名が検証できなかった場合、`false` が返されます。 -`secret` 引数には配列または文字列を指定できます。 文字列が与えられた場合、この -がシークレットとして使用されます。 配列が指定された場合、 +`secret` 引数には配列または文字列を指定できます。文字列が与えられた場合、この +がシークレットとして使用されます。配列が指定された場合、 シークレットごとにクッキーの署名を解除しようとします。 ### cookieParser.signedCookies(cookie, secret) オブジェクトが与えられた場合、キーに対して反復処理を行い、任意の値が -署名された Cookie であるかどうかを確認します。 署名されたCookieで署名が有効な場合、 キー +署名された Cookie であるかどうかを確認します。署名されたCookieで署名が有効な場合、 キー はオブジェクトから削除され、返された新しいオブジェクトに追加されます。 -`secret` 引数には配列または文字列を指定できます。 文字列が与えられた場合、この -がシークレットとして使用されます。 配列が指定された場合、 +`secret` 引数には配列または文字列を指定できます。文字列が与えられた場合、この +がシークレットとして使用されます。配列が指定された場合、 シークレットごとにクッキーの署名を解除しようとします。 ## 例 diff --git a/src/content/pages/ja/resources/middleware/cookie-session.mdx b/src/content/pages/ja/resources/middleware/cookie-session.mdx index b4f722fc95..dcc60268b8 100644 --- a/src/content/pages/ja/resources/middleware/cookie-session.mdx +++ b/src/content/pages/ja/resources/middleware/cookie-session.mdx @@ -16,7 +16,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa シンプルなクッキーベースのセッションミドルウェア。 ユーザーセッションは、サーバー上または -クライアント上での2つの主要な方法で保存できます。 ユーザーセッションは、サーバー上または +クライアント上での2つの主要な方法で保存できます。ユーザーセッションは、サーバー上または クライアント上での2つの主要な方法で保存できます。 クライアントのセッションデータをクッキーに保存します。 [express-session](https://www.npmjs.com/package/express-session) は、クッキー内にクライアントにセッション識別子のみを格納し、サーバーに @@ -44,7 +44,7 @@ to extend the session as your application needs. ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは [`npm install` コマンド](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): @@ -80,7 +80,7 @@ app.use( ### cookieSession(options) -指定されたオプションで新しいcookieセッションミドルウェアを作成します。 指定されたオプションで新しいcookieセッションミドルウェアを作成します。 This middleware +指定されたオプションで新しいcookieセッションミドルウェアを作成します。指定されたオプションで新しいcookieセッションミドルウェアを作成します。 This middleware will attach the property `session` to `req`, which provides an object representing the loaded session. このセッションは、リクエストで有効なセッションが 提供されなかった場合、またはリクエストからロードされたセッションのいずれかである。 @@ -125,9 +125,9 @@ Cookie の値の署名と検証に使用するキーのリスト、または設 - `expires`: Cookieの有効期限を示す`Date`オブジェクト(デフォルトではセッション終了時に有効期限が切れます)。 - `path`: クッキーのパスを示す文字列(デフォルトでは `/`)。 - `domain`: Cookie のドメインを示す文字列 (デフォルトではありません)。 -- `partitioned`: [CHIPS Update](https://developers.google.com/privacy-sandbox/3pcd/chips) (デフォルトでは `false` )のためにChromeのクッキーを分割するかどうかを示すブール値。 これがtrueの場合、埋め込まれたサイトからのCookieは分割され、作成された同じトップレベルのサイトからのみ読み込み可能になります。 これがtrueの場合、埋め込まれたサイトからのCookieは分割され、作成された同じトップレベルのサイトからのみ読み込み可能になります。 -- `priority`: Cookie の優先度を示す文字列。 これは`'low'`、`'medium'`、または`'high'`に設定できます。 これは`'low'`、`'medium'`、または`'high'`に設定できます。 -- `sameSite`: クッキーが「同じサイト」クッキーであるかどうかを示す真偽値または文字列(デフォルトでは`false`)。 これは`'strict'`、`'lax'`、`'none'`、`true`('strict'にマップされます)に設定できます。 これは`'strict'`、`'lax'`、`'none'`、`true`('strict'にマップされます)に設定できます。 +- `partitioned`: [CHIPS Update](https://developers.google.com/privacy-sandbox/3pcd/chips) (デフォルトでは `false` )のためにChromeのクッキーを分割するかどうかを示すブール値。 これがtrueの場合、埋め込まれたサイトからのCookieは分割され、作成された同じトップレベルのサイトからのみ読み込み可能になります。これがtrueの場合、埋め込まれたサイトからのCookieは分割され、作成された同じトップレベルのサイトからのみ読み込み可能になります。 +- `priority`: Cookie の優先度を示す文字列。 これは`'low'`、`'medium'`、または`'high'`に設定できます。これは`'low'`、`'medium'`、または`'high'`に設定できます。 +- `sameSite`: クッキーが「同じサイト」クッキーであるかどうかを示す真偽値または文字列(デフォルトでは`false`)。 これは`'strict'`、`'lax'`、`'none'`、`true`('strict'にマップされます)に設定できます。これは`'strict'`、`'lax'`、`'none'`、`true`('strict'にマップされます)に設定できます。 - `secure`: CookieがHTTPSでのみ送信されるかどうかを示すブール値 (HTTPでは`false`、HTTPSではデフォルトでは`true`)。 `secure`: CookieがHTTPSでのみ送信されるかどうかを示すブール値 (HTTPでは`false`、HTTPSではデフォルトでは`true`)。 `true` と Node に設定されている場合。 sはTLS接続上で直接ではありません。 [set Express behind proxies](/guide/behind-proxies)またはクッキーが正しく設定されていない可能性があります。 - `httpOnly`: CookieがHTTP(S)経由でのみ送信されるかどうかを示すブール値で、クライアントJavaScript(デフォルトでは`true`)では使用できません。 - `signed`: Cookie を署名するかどうかを示す boolean (デフォルトでは `true` )。 @@ -151,7 +151,7 @@ Cookie の値の署名と検証に使用するキーのリスト、または設 ### req.sessionOptions -現在のリクエストのセッションオプションを表します。 現在のリクエストのセッションオプションを表します。 これらのオプションはミドルウェア構築時に提供されたものの +現在のリクエストのセッションオプションを表します。現在のリクエストのセッションオプションを表します。 これらのオプションはミドルウェア構築時に提供されたものの 浅いクローンです。 リクエストごとにクッキー設定の動作を変更するために変更することができます。 @@ -166,8 +166,7 @@ req.session = null; ### セッションを保存中 セッションの内容全体がクライアント側の Cookie に保持されるため、 -セッションは、`Set-Cookie` レスポンスヘッダーにクッキーを書き出すことによって「保存」されます。 -セッションの内容全体がクライアント側の Cookie に保持されるため、 +セッションは、`Set-Cookie` レスポンスヘッダーにクッキーを書き出すことによって「保存」されます。セッションの内容全体がクライアント側の Cookie に保持されるため、 セッションは、`Set-Cookie` レスポンスヘッダーにクッキーを書き出すことによって「保存」されます。 This is done automatically if there has been a change made to the session when the Node.js response headers are being written to the client and the session @@ -294,14 +293,14 @@ possible to exceed the maximum cookie size limits on different browsers. [RFC626 > の長さの合計で測定されます) 実際、この制限はブラウザによってわずかに異なります。 -[browser limits here](http://browsercookielimits.iain.guru) のリストを参照してください。 原則として、親指の +[browser limits here](http://browsercookielimits.iain.guru) のリストを参照してください。原則として、親指の はドメインあたり4093バイトを超えてはいけません。 セッションオブジェクトがエンコード時にブラウザの制限を超えるほど大きい場合。 はほとんどの場合、ブラウザはクッキーの保存を拒否します。 これにより、 ブラウザからのリクエストは、a) セッション 情報がない、またはb) -クッキーの制限を超えないように小さい古いセッション情報を使用します。 これにより、 +クッキーの制限を超えないように小さい古いセッション情報を使用します。これにより、 ブラウザからのリクエストは、a) セッション 情報がない、またはb) クッキーの制限を超えないように小さい古いセッション情報を使用します。 @@ -309,7 +308,7 @@ possible to exceed the maximum cookie size limits on different browsers. [RFC626 セッションオブジェクトがこれらの制限に達している場合、 セッション内のデータを、リクエストごとにブラウザから送信するのではなく、 サーバー上のデータベースからロードするかどうかを検討することをお勧めします。 または、 -[alternative session strategy](https://github.com/expressjs/session#compatible-session-stores) に移動します。 または、 +[alternative session strategy](https://github.com/expressjs/session#compatible-session-stores) に移動します。または、 [alternative session strategy](https://github.com/expressjs/session#compatible-session-stores) に移動します。 ## ライセンス diff --git a/src/content/pages/ja/resources/middleware/cors.mdx b/src/content/pages/ja/resources/middleware/cors.mdx index d89aba0cc2..5f681397a4 100644 --- a/src/content/pages/ja/resources/middleware/cors.mdx +++ b/src/content/pages/ja/resources/middleware/cors.mdx @@ -17,7 +17,7 @@ CORS is a [Node.js](https://nodejs.org/en/) middleware for [Express](/)/[Connect -**CORS の仕組み** このパッケージはレスポンスヘッダーを設定します。リクエストをブロックしません。 CORS はブラウザーによって強制されます。ヘッダーをチェックし、JavaScript がレスポンスを読み取れるかどうかを決定します。 ブラウザ以外のクライアント (curl, Postman, other servers) は CORS を完全に無視します。 詳細は [MDN CORS ガイド](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) を参照してください。 +**CORS の仕組み** このパッケージはレスポンスヘッダーを設定します。リクエストをブロックしません。 CORS はブラウザーによって強制されます。ヘッダーをチェックし、JavaScript がレスポンスを読み取れるかどうかを決定します。ブラウザ以外のクライアント (curl, Postman, other servers) は CORS を完全に無視します。詳細は [MDN CORS ガイド](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) を参照してください。 @@ -37,7 +37,7 @@ CORS is a [Node.js](https://nodejs.org/en/) middleware for [Express](/)/[Connect ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは [`npm install` コマンド](https://docs.npmjs.com/downloading-and-installing-packages-locally): @@ -188,7 +188,7 @@ routes. ### CORS設定をリクエストごとに動的にカスタマイズする -特定のルートやリクエストに異なるCORS設定を必要とするAPIでは、受信するリクエストに基づいて動的にCORSオプションを生成できます。 `cors` ミドルウェアは静的なオプションの代わりに関数を渡すことでこれを実現できます。 この関数は、受信リクエストごとに呼び出され、適切な CORS オプションを返すためにコールバックパターンを使用する必要があります。 +特定のルートやリクエストに異なるCORS設定を必要とするAPIでは、受信するリクエストに基づいて動的にCORSオプションを生成できます。 `cors` ミドルウェアは静的なオプションの代わりに関数を渡すことでこれを実現できます。この関数は、受信リクエストごとに呼び出され、適切な CORS オプションを返すためにコールバックパターンを使用する必要があります。 この関数は受け入れられます: @@ -236,19 +236,19 @@ app.listen(80, function () { ## 設定オプション -- `origin`: **Access-Control-Allow-Origin** CORS ヘッダーを設定します。 可能な値: +- `origin`: **Access-Control-Allow-Origin** CORS ヘッダーを設定します。可能な値: - `Boolean` - `origin`を`true`に設定し、`req.header('Origin')`で定義されている[request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09)を反映させるか、CORSを無効にするには`false`に設定します。 - - `String` - 特定の原点に`origin`を設定します。 例えば、 + - `String` - 特定の原点に`origin`を設定します。例えば、 - `"http://example.com"` からのリクエストのみ許可されます。 - すべてのドメインを許可する `"*"` 。 - - `RegExp` - リクエストオリジンをテストするために使用される正規表現パターンに`origin`を設定します。 一致する場合はリクエストのオリジンが反映されます。 例えば、パターン `/example\.com$/` は "example.com" で終わるオリジンからのリクエストを反映します。 - - `Array` - 有効な原点の配列に`origin`を設定します。 各原点は `String` または `RegExp` にすることができます。 例えば、 `["http://example1.com", /\.example2\.com$/]`は"http://example1.com"または"example2.com"のサブドメインからのリクエストを受け付けます。 - - `Function` - カスタムロジックを実装する関数に`origin`を設定します。 この関数はリクエストのオリジンを最初のパラメータとして受け取り、コールバックを `callback(err, と呼ばれます。 origin)`, `origin` は `origin` オプションの関数ではない値です。 -- `methods`: **Access-Control-Allow-Methods** CORS ヘッダーを設定します。 カンマ区切り文字列 (ex: 'GET,PUT,POST') または配列 (例: `['GET', 'PUT', 'POST']`) を想定します。 -- `allowedHeaders`: **Access-Control-Allow-Headers** CORS ヘッダーを設定します。 カンマ区切り文字列 (例: 'Content-Type,Authorization') または配列 (例: `['Content-Type', 'Authorization']`) が期待されます。 指定しない場合は、リクエストの **Access-Control-Request-Headers** ヘッダーに指定されたヘッダーを反映します。 -- `exposedHeaders`: **Access-Control-Expose-Headers** CORS ヘッダーを設定します。 カンマ区切り文字列 (例: 'Content-Range,X-Content-Range') または配列 (例: `['Content-Range', 'X-Content-Range']`) を期待します。 指定されていない場合、カスタムヘッダーは公開されません。 -- `credentials`: **Access-Control-Allow-Credentials** CORS ヘッダーを設定します。 ヘッダを渡す場合は `true` に設定します。それ以外の場合は省略されます。 -- `maxAge`: **Access-Control-Max-Age** CORS ヘッダーを設定します。 ヘッダを渡すための整数に設定します。それ以外の場合は省略されます。 + - `RegExp` - リクエストオリジンをテストするために使用される正規表現パターンに`origin`を設定します。一致する場合はリクエストのオリジンが反映されます。例えば、パターン `/example\.com$/` は "example.com" で終わるオリジンからのリクエストを反映します。 + - `Array` - 有効な原点の配列に`origin`を設定します。各原点は `String` または `RegExp` にすることができます。例えば、 `["http://example1.com", /\.example2\.com$/]`は"http://example1.com"または"example2.com"のサブドメインからのリクエストを受け付けます。 + - `Function` - カスタムロジックを実装する関数に`origin`を設定します。この関数はリクエストのオリジンを最初のパラメータとして受け取り、コールバックを `callback(err, と呼ばれます。 origin)`, `origin` は `origin` オプションの関数ではない値です。 +- `methods`: **Access-Control-Allow-Methods** CORS ヘッダーを設定します。カンマ区切り文字列 (ex: 'GET,PUT,POST') または配列 (例: `['GET', 'PUT', 'POST']`) を想定します。 +- `allowedHeaders`: **Access-Control-Allow-Headers** CORS ヘッダーを設定します。カンマ区切り文字列 (例: 'Content-Type,Authorization') または配列 (例: `['Content-Type', 'Authorization']`) が期待されます。指定しない場合は、リクエストの **Access-Control-Request-Headers** ヘッダーに指定されたヘッダーを反映します。 +- `exposedHeaders`: **Access-Control-Expose-Headers** CORS ヘッダーを設定します。カンマ区切り文字列 (例: 'Content-Range,X-Content-Range') または配列 (例: `['Content-Range', 'X-Content-Range']`) を期待します。指定されていない場合、カスタムヘッダーは公開されません。 +- `credentials`: **Access-Control-Allow-Credentials** CORS ヘッダーを設定します。ヘッダを渡す場合は `true` に設定します。それ以外の場合は省略されます。 +- `maxAge`: **Access-Control-Max-Age** CORS ヘッダーを設定します。ヘッダを渡すための整数に設定します。それ以外の場合は省略されます。 - `preflightContinue`: CORS のプリフライト応答を次のハンドラに渡します。 - `optionsSuccessStatus`: いくつかのレガシーブラウザ(IE11、様々なSmartTVs)が`204`でチョークするため、`OPTIONS`リクエストに成功するために使用するステータスコードを提供します。 @@ -271,11 +271,11 @@ app.listen(80, function () { ### "CORSは私のAPIを不正アクセスから保護します" -**いいえ** CORS はアクセス制御ではありません。 どの HTTP クライアント (curl, Postman, 別のサーバー) でも CORS 設定に関係なく API を呼び出すことができます。 APIを保護するには認証と認証を使用してください。 +**いいえ** CORS はアクセス制御ではありません。どの HTTP クライアント (curl, Postman, 別のサーバー) でも CORS 設定に関係なく API を呼び出すことができます。 APIを保護するには認証と認証を使用してください。 ### 「`origin: 'http://example.com'` を設定すると、ドメインが私のサーバーにアクセスできることだけを意味します」 -**いいえ** ブラウザはそのオリジンからのJavaScriptのみが応答を読み取ることができます。 サーバーは引き続きすべてのリクエストに応答します。 +**いいえ** ブラウザはそのオリジンからのJavaScriptのみが応答を読み取ることができます。サーバーは引き続きすべてのリクエストに応答します。 ## ライセンス diff --git a/src/content/pages/ja/resources/middleware/errorhandler.mdx b/src/content/pages/ja/resources/middleware/errorhandler.mdx index 50432e7ef1..b12561091d 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 @@ -34,7 +34,7 @@ for the response between HTML, JSON, and plain text. ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは [`npm install` コマンド](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): @@ -66,7 +66,7 @@ var errorhandler = require('errorhandler'); ##### ログ エラーとともに呼び出される関数と、 -エラーの文字列表現を提供します。 任意の場所にエラーを書き込むために使用するか、 +エラーの文字列表現を提供します。任意の場所にエラーを書き込むために使用するか、 `false` に設定すると、応答内のエラーのみを返します。 Called as `log(err, str, req, res)` where `err` is the `Error` object, `str` is a string representation of the error, `req` is the request object and `res` is the diff --git a/src/content/pages/ja/resources/middleware/index.mdx b/src/content/pages/ja/resources/middleware/index.mdx index 266c6cdae6..94260cee4f 100644 --- a/src/content/pages/ja/resources/middleware/index.mdx +++ b/src/content/pages/ja/resources/middleware/index.mdx @@ -33,8 +33,8 @@ These are some additional popular middleware modules. この情報は、 - Expressjsチームがメンテナンスしていないサードパーティのサイト、製品、またはモジュールを指します。 - ここでの掲載は、 Expressjsプロジェクトチームの推奨または推奨を構成するものではありません。 + Expressjsチームがメンテナンスしていないサードパーティのサイト、製品、またはモジュールを指します。ここでの掲載は、 + Expressjsプロジェクトチームの推奨または推奨を構成するものではありません。 | Middleware module | 説明 | diff --git a/src/content/pages/ja/resources/middleware/method-override.mdx b/src/content/pages/ja/resources/middleware/method-override.mdx index ca01f733c1..ad3eeb9f5c 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 @@ -18,7 +18,7 @@ PUTやDELETEなどのHTTP動詞をクライアントがサポートしていな ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは [`npm install` コマンド](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): @@ -40,13 +40,13 @@ the `csurf` module). ### methodOverride(getter, options) 新しい -値で`req.method`プロパティをオーバーライドするために、新しいミドルウェア関数を作成します。 この値は `getter` から取り出されます。 +値で`req.method`プロパティをオーバーライドするために、新しいミドルウェア関数を作成します。この値は `getter` から取り出されます。 -- `getter` - リクエストのオーバーライドされたリクエストメソッドを検索するために使用するゲッター。 (デフォルト: `X-HTTP-Method-Override` ) -- `options.methods` - メソッドのオーバーライド値をチェックするには、元のリクエストに許可されているメソッドを指定します。 (デフォルト: `['POST']`) +- `getter` - リクエストのオーバーライドされたリクエストメソッドを検索するために使用するゲッター。(デフォルト: `X-HTTP-Method-Override` ) +- `options.methods` - メソッドのオーバーライド値をチェックするには、元のリクエストに許可されているメソッドを指定します。(デフォルト: `['POST']`) foundメソッドがnode.jsコアでサポートされている場合は、 `req. ethod`は、もともとその値であったかのように、この値を -に設定します。 以前の `req.method` +に設定します。以前の `req.method` の値は `req.originalMethod` に保存されます。 #### 取得 @@ -57,16 +57,16 @@ expected to be returned. 文字列が指定された場合、以下のルール メソッドを検索するために使用されます。 - 文字列が `X-`で始まる場合。 次に、ヘッダーの名前として扱われ、そのヘッダー - がメソッドのオーバーライドに使用されます。 リクエストに同じヘッダーが複数回含まれている場合、最初の + がメソッドのオーバーライドに使用されます。リクエストに同じヘッダーが複数回含まれている場合、最初の が使用されます。 - その他の文字列はすべて、URL クエリ文字列内のキーとして扱われます。 #### options.methods これにより、リクエストされた _MUST_ メソッドのオーバーライド値を -でチェックするために、どのメソッドを指定できるようになります。 デフォルトは `POST` メソッドのみで、 -オーバーライドする唯一のメソッドです。 ここではより多くのメソッドを指定することができますが、セキュリティ -の問題が発生し、リクエストがキャッシュを通過すると変な動作が発生する可能性があります。 この値は大文字小文字のメソッドの配列 +でチェックするために、どのメソッドを指定できるようになります。デフォルトは `POST` メソッドのみで、 +オーバーライドする唯一のメソッドです。ここではより多くのメソッドを指定することができますが、セキュリティ +の問題が発生し、リクエストがキャッシュを通過すると変な動作が発生する可能性があります。この値は大文字小文字のメソッドの配列 です。 `null`はすべてのメソッドを許可するように指定できます。 ## 例 @@ -147,7 +147,7 @@ app.use(methodOverride('X-Method-Override')); // IBM ### カスタムロジック設定 -`getter` の関数を使って、任意の種類のカスタムロジックを実装できます。 以下の +`getter` の関数を使って、任意の種類のカスタムロジックを実装できます。以下の は、 `method-override@1`にあった`req.body` を参照するためのロジックを実装しています。 ```js diff --git a/src/content/pages/ja/resources/middleware/morgan.mdx b/src/content/pages/ja/resources/middleware/morgan.mdx index 1f0d874a0b..27c5626af8 100644 --- a/src/content/pages/ja/resources/middleware/morgan.mdx +++ b/src/content/pages/ja/resources/middleware/morgan.mdx @@ -8,19 +8,19 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; HTTPリクエストロガーミドルウェア for node.js -> [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan) にちなんで命名された番組は、完成するまで見てはいけません。 +> Named after [Dexter](https://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは [`npm install` コマンド](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): @@ -35,6 +35,16 @@ HTTPリクエストロガーミドルウェア for node.js ## API +For ES Modules: + +{/* eslint-disable no-unused-var */} + +```js +import morgan from 'morgan'; +``` + +For CommonJS: + {/* eslint-disable no-unused-var */} ```js @@ -43,13 +53,12 @@ var morgan = require('morgan'); ### モルガン(書式、オプション) -与えられた `format` と `options` を使用して、新しいモーガンロガーミドルウェア関数を作成します。 -引数`format`は、定義済みの名前の文字列を指定することができます (以下を参照してください) +与えられた `format` と `options` を使用して、新しいモーガンロガーミドルウェア関数を作成します。引数`format`は、定義済みの名前の文字列を指定することができます (以下を参照してください) フォーマット文字列の文字列、またはログエントリを生成する関数。 `format`関数は、`tokens`、`req`、`res`の3つの引数で呼び出されます。 `tokens` がすべて定義されたトークンを持つオブジェクトである場合、`req` はHTTPリクエスト、`res` -はHTTPレスポンスです。 関数はログ +はHTTPレスポンスです。関数はログ 行になる文字列を返すことが期待されます。ログをスキップするには`undefined` / `null`を返します。 #### 定義済みの書式文字列の使用 @@ -78,10 +87,12 @@ morgan(function (tokens, req, res) { tokens.method(req, res), tokens.url(req, res), tokens.status(req, res), - tokens.res(req, res, 'content-length'), '-', - tokens['response-time'](https://github.com/expressjs/morgan/blob/HEAD/req, res), 'ms' - ].join(' ') -}) + tokens.res(req, res, 'content-length'), + '-', + tokens['response-time'](req, res), + 'ms', + ].join(' '); +}); ``` #### オプション @@ -90,13 +101,13 @@ Morgan は options オブジェクトでこれらのプロパティを受け付 ##### immediate -レスポンスの代わりにリクエスト時にログ行を書き込みます。 This means that a requests will +レスポンスの代わりにリクエスト時にログ行を書き込みます。 This means that requests will be logged even if the server crashes, *but data from the response (like the response code, content length, etc.) logged*はできません。 ##### スキップ -ログをスキップするかどうかを決定する関数。デフォルトは `false` です。 この関数 +ログをスキップするかどうかを決定する関数。デフォルトは `false` です。この関数 は`skip(req, res)` として呼び出されます。 {/* eslint-disable no-undef */} @@ -114,6 +125,33 @@ morgan('combined', { ログ行を書くためのストリームを出力します。デフォルトは `process.stdout` です。 +If the stream is in object mode (`stream.writableObjectMode` is `true`) and the +format function returns an object, the object is written to the stream as-is, +without a trailing newline. This allows passing structured log entries to +loggers that accept objects: + +{/* eslint-disable no-undef */} + +```js +morgan( + function (tokens, req, res) { + return { + method: tokens.method(req, res), + url: tokens.url(req, res), + status: Number(tokens.status(req, res)), + }; + }, + { + stream: { + writableObjectMode: true, + write: function (entry) { + // entry is the object returned by the format function + }, + }, + } +); +``` + #### 定義済みのフォーマット 様々な事前定義されたフォーマットが用意されています: @@ -151,6 +189,11 @@ for information codes. GET /dev 200 0.224 ms - 2 ``` +Coloring is disabled when the [`NO_COLOR`](https://no-color.org) environment +variable is set to any non-empty value, in which case the output above is +written without any escape sequences. The variable is read once, when `morgan` +is first required. + ##### 短い デフォルトよりも短く、応答時間も含まれます。 @@ -175,8 +218,7 @@ GET /tiny 200 2 - 0.188 ms ##### 新しいトークンを作成中 -トークンを定義するには、名前とコールバック関数で `morgan.token()` を呼び出します。 -このコールバック関数は文字列の値を返すことが期待されます。 この場合、返される値は +トークンを定義するには、名前とコールバック関数で `morgan.token()` を呼び出します。このコールバック関数は文字列の値を返すことが期待されます。この場合、返される値は は ":type" として使用できます: {/* eslint-disable no-undef */} @@ -192,11 +234,11 @@ morgan.token('type', function (req, res) { The token function is expected to be called with the arguments `req` and `res`, representing the HTTP request and HTTP response. Additionally, the token can accept further arguments of -it's choosing to customize behavior. +its choosing to customize behavior. ##### :date[format] -UTCの現在の日付と時刻。 利用可能なフォーマットは次のとおりです。 +UTCの現在の日付と時刻。利用可能なフォーマットは次のとおりです。 - `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`) - ISO 8601 の日付時刻形式 (`2000-10-10T13:55:36.000Z`) の`iso` @@ -218,11 +260,11 @@ Node.js プロセスのプロセス ID がリクエストを処理します。 ##### -リクエストの Referrer ヘッダー。 これは、標準のスペルの間違いの Referer ヘッダが存在する場合に使用します。そうでなければ、Referrerです。 +リクエストの Referrer ヘッダー。 This will use the standard mis-spelled Referer header if it exists, otherwise Referrer. ##### :remote-addr -リクエストのリモートアドレス これは `req.ip` を使用します。それ以外の場合は、標準 `req.connection.remoteAddress` 値 (ソケットアドレス) を使用します。 +リクエストのリモートアドレスこれは `req.ip` を使用します。それ以外の場合は、標準 `req.connection.remoteAddress` 値 (ソケットアドレス) を使用します。 ##### :remote-user @@ -230,12 +272,12 @@ Node.js プロセスのプロセス ID がリクエストを処理します。 ##### :req[header] -リクエストの与えられた `header` 。 ヘッダが存在しない場合、 +リクエストの与えられた `header` 。ヘッダが存在しない場合、 値はログに`"-"`として表示されます。 ##### :res[header] -レスポンスの `header` を指定しました。 ヘッダが存在しない場合、 +レスポンスの `header` を指定しました。ヘッダが存在しない場合、 値はログに`"-"`として表示されます。 ##### :responsetime[digits] @@ -264,7 +306,7 @@ the request), then the status will be empty (displayed as `"-"` in the log). ##### -リクエストの URL `req.originalUrl` が存在する場合は使用します。存在しない場合は、 `req.url` を使用します。 +リクエストの URL This will use `req.originalUrl` if it exists, otherwise `req.url`. ##### :user-agent @@ -272,14 +314,14 @@ the request), then the status will be empty (displayed as `"-"` in the log). ### morgan.compile(format) -書式文字列を `format` 関数に `morgan` で使用するようにコンパイルします。 フォーマット文字列 +書式文字列を `format` 関数に `morgan` で使用するようにコンパイルします。フォーマット文字列 は、単一のログ行を表し、トークン構文を利用できる文字列です。 -トークンは `:token-name` による参照です。 If tokens accept arguments, they can +Tokens are referenced by `:token-name`. If tokens accept arguments, they can be passed using `[]`, for example: `:token-name[pretty]` would pass the string `'pretty'` as an argument to the token `token-name`. The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and -`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and +`res`, where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res` is the HTTP response. 関数はログをスキップするためにログ行、 または `undefined` / `null` になる文字列を返します。 @@ -290,7 +332,7 @@ The function returned from `morgan.compile` takes three arguments `tokens`, `req ### エクスプレス/接続 -Apache の組み合わせ形式ですべてのリクエストを STDOUT にログ収集するサンプルアプリ +Sample app that will log all requests in the Apache combined format to STDOUT ```js var express = require('express'); @@ -307,7 +349,7 @@ app.get('/', function (req, res) { ### vanilla http サーバー -Apache の組み合わせ形式ですべてのリクエストを STDOUT にログ収集するサンプルアプリ +Sample app that will log all requests in the Apache combined format to STDOUT ```js var finalhandler = require('finalhandler'); @@ -426,12 +468,12 @@ app.get('/', function (req, res) { ### カスタムトークンフォーマットを使用 -カスタムトークンフォーマットを使用するサンプルアプリ。 これにより、すべてのリクエストに ID が追加され、`:id` トークンを使用して表示されます。 +カスタムトークンフォーマットを使用するサンプルアプリ。これにより、すべてのリクエストに ID が追加され、`:id` トークンを使用して表示されます。 ```js var express = require('express'); var morgan = require('morgan'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); morgan.token('id', function getId(req) { return req.id; diff --git a/src/content/pages/ja/resources/middleware/multer.mdx b/src/content/pages/ja/resources/middleware/multer.mdx index 1cd3583560..b7e9f96a26 100644 --- a/src/content/pages/ja/resources/middleware/multer.mdx +++ b/src/content/pages/ja/resources/middleware/multer.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -19,23 +19,6 @@ Multer は `multipart/form-data` を扱うための node.js ミドルウェア **注意**: Multer はマルチパートでないフォームを処理しません (`multipart/form-data`)。 -## 翻訳 - -このREADMEは他の言語でも利用できます: - -| | | -| ---------------------------------------------------------------------------------------- | ----------------- | -| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | アラビア文字 | -| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | 中国語 | -| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | フランス語 | -| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean | -| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | ポルトガル語 (BR) | -| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | ロシア語 | -| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | スペイン語 | -| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek | -| [Vie\ \ 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) | トルコ語 | - ## インストール @@ -119,7 +102,7 @@ multer が HTML 形式でどのように使用されるかについての例を ``` -次に、javascriptファイルで、ファイルと本文の両方にアクセスするために、これらの行を追加します。 アップロード関数のフォームから `name` フィールドの値を使用することが重要です。 これは、リクエストのどのフィールドにファイルを探すべきかをmulterに伝えます。 次に、javascriptファイルで、ファイルと本文の両方にアクセスするために、これらの行を追加します。 アップロード関数のフォームから `name` フィールドの値を使用することが重要です。 これは、リクエストのどのフィールドにファイルを探すべきかをmulterに伝えます。 これらのフィールドが HTML フォームとサーバーで同じでない場合、アップロードに失敗します: +次に、javascriptファイルで、ファイルと本文の両方にアクセスするために、これらの行を追加します。アップロード関数のフォームから `name` フィールドの値を使用することが重要です。これは、リクエストのどのフィールドにファイルを探すべきかをmulterに伝えます。次に、javascriptファイルで、ファイルと本文の両方にアクセスするために、これらの行を追加します。 アップロード関数のフォームから `name` フィールドの値を使用することが重要です。 これは、リクエストのどのフィールドにファイルを探すべきかをmulterに伝えます。 これらのフィールドが HTML フォームとサーバーで同じでない場合、アップロードに失敗します: ```javascript const multer = require('multer'); @@ -131,23 +114,26 @@ app.post('/stats', upload.single('uploaded_file'), function (req, res) { }); ``` +Complete client-side and server-side examples (browser `FormData` uploads of a +blob and of an image) are in the [`examples/`](https://github.com/expressjs/multer/blob/HEAD/examples/) folder. + ## API ### ファイル情報 各ファイルには以下の情報が含まれています: -| キー | 説明 | メモ | -| -------------- | ------------------------------------------ | --------------- | -| `fieldname` | フォームで指定されたフィールド名 | | -| `originalname` | ユーザーのコンピューター上のファイルの名前 | | -| `encoding` | ファイルのエンコードタイプ | | -| `mimetype` | ファイルの Mime タイプ | | -| `size` | バイト単位のファイルのサイズ | | -| `destination` | ファイルが保存されたフォルダ | `DiskStorage` | -| `filename` | `destination`内のファイルの名前 | `DiskStorage` | -| `path` | アップロードされたファイルへのフルパス | `DiskStorage` | -| `buffer` | ファイル全体の `Buffer` | `MemoryStorage` | +| キー | 説明 | メモ | +| -------------- | ----------------------------------------------------------------------------------- | --------------- | +| `fieldname` | フォームで指定されたフィールド名 | | +| `originalname` | Name of the file on the user's computer, or the full path when `preservePath: true` | | +| `encoding` | ファイルのエンコードタイプ | | +| `mimetype` | ファイルの Mime タイプ | | +| `size` | バイト単位のファイルのサイズ | | +| `destination` | ファイルが保存されたフォルダ | `DiskStorage` | +| `filename` | `destination`内のファイルの名前 | `DiskStorage` | +| `path` | アップロードされたファイルへのフルパス | `DiskStorage` | +| `buffer` | ファイル全体の `Buffer` | `MemoryStorage` | ### `multer(opts)` @@ -164,11 +150,15 @@ Multer に渡すことができるオプションは以下のとおりです。 | キー | 説明 | | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `defCharset` | Default character set to use for text field values that do not declare one. Default: `'utf8'` | +| `defParamCharset` | 拡張パラメータではない (明示的な文字セットを含む) 部品ヘッダーパラメータの値(ファイル名など)に使用するデフォルトの文字セット。 デフォルト: `'latin1'` デフォルト: `'latin1'` | | `dest` または `storage` | ファイルを保存する場所 | | `fileFilter` | 受け入れられるファイルを制御する関数 | +| `fileHwm` | `highWaterMark` of each file stream (`file.stream`). Default: busboy's default | +| `highWaterMark` | `highWaterMark` of the multipart parser stream. Default: busboy's default | | `limits` | アップロードしたデータの制限 | -| `preservePath` | ベース名の代わりにファイルの完全なパスを保持します | -| `defParamCharset` | 拡張パラメータではない (明示的な文字セットを含む) 部品ヘッダーパラメータの値(ファイル名など)に使用するデフォルトの文字セット。 デフォルト: `'latin1'` デフォルト: `'latin1'` | +| `preservePath` | Keep the full client-supplied path in `file.originalname` instead of just the base name | +| `streamHandler` | Function that feeds the request body to busboy; defaults to `req.pipe(busboy)` | In an average web app, only `dest` might be required, and configured as shown in the following example. @@ -177,6 +167,14 @@ the following example. const upload = multer({ dest: 'uploads/' }); ``` +When `preservePath` is enabled, Multer passes the incoming filename through with +any path segments provided by the client. This is exposed as `file.originalname`; +it does not change the destination folder, create directories, or sanitize the +path for you. `file.originalname` is always client-supplied and should be treated +as untrusted; with `preservePath` it additionally contains the path segments the +client sent. Normalize or validate it before using it in a custom `filename` or +storage engine. + アップロードをもっと制御したい場合は、`dest` の代わりに `storage` オプションを使用します。 Multer はストレージエンジン `DiskStorage` と `MemoryStorage` を搭載しています。より多くのエンジンはサードパーティから入手できます。 Multer はストレージエンジン `DiskStorage` @@ -185,23 +183,25 @@ const upload = multer({ dest: 'uploads/' }); #### `.single(fieldname)` `fieldname`という名前のファイルを受け入れます。 単一のファイルは -を `req.file` に格納します。 単一のファイルは +を `req.file` に格納します。単一のファイルは を `req.file` に格納します。 #### `.array(fieldname[, maxCount])` -`fieldname`という名前のファイルの配列を受け入れます。 必要に応じて、 -が `maxCount`ファイルよりも大きい場合にエラーが発生します。 ワイヤ上にあるすべてのファイルを受け入れます。 ファイルの配列は +`fieldname`という名前のファイルの配列を受け入れます。必要に応じて、 +が `maxCount`ファイルよりも大きい場合にエラーが発生します。ワイヤ上にあるすべてのファイルを受け入れます。 ファイルの配列は `req.files` に格納されます。 +Files skipped by `fileFilter` do not count towards `maxCount`. Use +`limits.files` to bound how many files are read from a request. + #### `.fields(fields)` `fields`で指定されたファイルのミックスを受け入れます。 `fields`で指定されたファイルのミックスを受け入れます。 ファイル の配列を持つオブジェクトは`req.files`に保存されます。 `fields`は、`name`とオプションで`maxCount`を持つオブジェクトの配列でなければなりません。 -例 -例 +例例 ```javascript [ @@ -212,19 +212,18 @@ const upload = multer({ dest: 'uploads/' }); #### `.none()` -テキストフィールドのみ受け入れます。 ファイルのアップロードが完了した場合は、 -"LIMIT_UNEXPECTED_FILE"でエラーが発生します。 +テキストフィールドのみ受け入れます。 If any file upload is made, error with code +`LIMIT_UNEXPECTED_FILE` will be issued. #### `.any()` -ワイヤ上にあるすべてのファイルを受け入れます。 ファイルの配列は +Accepts all files that come over the wire. ファイルの配列は `req.files` に格納されます。 -**警告:** ユーザーがアップロードするファイルを常に処理していることを確認してください。 -**警告:** ユーザーがアップロードするファイルを常に処理していることを確認してください。 +**警告:** ユーザーがアップロードするファイルを常に処理していることを確認してください。**警告:** ユーザーがアップロードするファイルを常に処理していることを確認してください。 悪意のあるユーザーが予想していなかったルートに ファイルをアップロードできるため、multer をグローバルミドルウェアとして追加しないでください。 アップロードされたファイルを処理しているルート -でのみこの機能を使用してください。 アップロードされたファイルを処理しているルート +でのみこの機能を使用してください。アップロードされたファイルを処理しているルート でのみこの機能を使用してください。 ### `storage` @@ -234,22 +233,26 @@ const upload = multer({ dest: 'uploads/' }); ディスクストレージエンジンは、ディスクにファイルを保存することを完全に制御します。 ```javascript +const crypto = require('crypto'); + const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/tmp/my-uploads'); }, filename: function (req, file, cb) { - const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); - cb(null, file.fieldname + '-' + uniqueSuffix); + crypto.randomBytes(16, function (err, raw) { + if (err) return cb(err); + cb(null, file.fieldname + '-' + raw.toString('hex')); + }); }, }); const upload = multer({ storage: storage }); ``` -`destination` と `filename` の2つのオプションが利用できます。 これらはどちらも、ファイルをどこに保存するかを決める -関数です。 これらはどちらも、ファイルをどこに保存するかを決める -関数です。 +There are three options available: `destination`, `filename` and `flush`. All of +them except `flush` are functions that determine where the file should be +stored. `destination` is used to determine within which folder the uploaded files should be stored. これは文字列として与えることもできます(例: `'/tmp/uploads`)。 @@ -258,7 +261,7 @@ be stored. これは文字列として与えることもできます(例: `'/tmp **注意:** 関数として `destination` を指定するときにディレクトリを作成します。 文字列を渡すとき、multer は -ディレクトリが作成されていることを確認します。 文字列を渡すとき、multer は +ディレクトリが作成されていることを確認します。文字列を渡すとき、multer は ディレクトリが作成されていることを確認します。 `destination` is used to determine within which folder the uploaded files should @@ -273,18 +276,26 @@ be stored. 各関数はリクエスト(`req`)と ファイル(`file`)に関する情報の両方を渡され、決定を助けます。 -`req.body` はまだ完全に入力されていない可能性があります。 これは、クライアントがフィールドとファイルをサーバーに送信する +`req.body` はまだ完全に入力されていない可能性があります。これは、クライアントがフィールドとファイルをサーバーに送信する オーダーに依存します。 コールバックで使用される呼び出し規約(最初のパラメータとして null を渡す必要がある)を理解するには、 [Node] を参照してください。 s error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors) +`flush` is an optional boolean. When set to `true`, the file data is flushed to +disk with an `fsync` call before the upload handler runs, which prevents data +loss if the process or the system crashes while the data is still sitting in +the operating system's page cache. It is disabled by default because forcing a +disk flush on every upload has a performance cost. Note that this syncs the +file contents only; if the new directory entry must survive a crash as well, +fsync the destination directory yourself. + #### `MemoryStorage` メモリストレージエンジンはファイルを `Buffer` オブジェクトとして保存します。 -にはオプションはありません。 -にはオプションはありません。 +にはオプションはありません。 It +doesn't have any options. ```javascript const storage = multer.memoryStorage(); @@ -300,20 +311,36 @@ memory storage is used. ### `limits` -次のオプションプロパティのサイズ制限を指定するオブジェクト。 次のオプションプロパティのサイズ制限を指定するオブジェクト。 Multer はこのオブジェクトを busboy に直接渡し、プロパティの詳細は [busboy's page](https://github.com/mscdex/busboy#busboy-methods) にあります。 +An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#exports). + +`limits` can also be a function that receives the request and returns such an +object. It is called once per request, before parsing starts, so limits can +depend on e.g. the authenticated user: + +```javascript +const upload = multer({ + limits: function (req) { + return { fileSize: req.user.maxUploadSize }; + }, +}); +``` + +Limits apply to the whole request; there is no per-file limit. To restrict +individual files by type or name, use `fileFilter` or a custom storage engine. 次の整数値が使用できます。 -| キー | 説明 | デフォルト | -| ------------------- | -------------------------------------------------------------------------- | ---------- | -| `fieldNameSize` | 最大フィールド名のサイズ | 100 バイト | -| `fieldSize` | 最大フィールド値のサイズ (バイト単位) | 1MB | -| `fields` | ファイル以外のフィールドの最大数 | Infinity | -| `fileSize` | マルチパート形式の場合、最大ファイルサイズ(バイト単位) | Infinity | -| `files` | 複数形の場合、ファイルフィールドの最大数 | Infinity | -| `parts` | マルチパートフォームの場合、部品の最大数 (フィールド + ファイル) | Infinity | -| `headerPairs` | マルチパートフォームの場合、解析する最大ヘッダーキー=>値のペアの数 | 2000 | -| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinity | +| キー | 説明 | デフォルト | +| ---------------------- | ------------------------------------------------------------------------------- | ---------- | +| `fieldNameSize` | 最大フィールド名のサイズ | Infinity | +| `fieldSize` | 最大フィールド値のサイズ (バイト単位) | 1MB | +| `fields` | ファイル以外のフィールドの最大数 | Infinity | +| `fileSize` | マルチパート形式の場合、最大ファイルサイズ(バイト単位) | Infinity | +| `files` | 複数形の場合、ファイルフィールドの最大数 | Infinity | +| `parts` | マルチパートフォームの場合、部品の最大数 (フィールド + ファイル) | Infinity | +| `headerPairs` | マルチパートフォームの場合、解析する最大ヘッダーキー=>値のペアの数 | 2000 | +| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinity | +| `fieldArrayIndexLimit` | Max numeric array index accepted inside a field name (e.g. `a[3]` uses index 3) | Infinity | 制限を指定することは、サービス妨害(DoS)攻撃からサイトを保護するのに役立ちます。 @@ -338,6 +365,30 @@ function fileFilter(req, file, cb) { } ``` +### `streamHandler` + +By default Multer reads the request with `req.pipe(busboy)`. Some platforms +consume the request body before your handlers run, so there is nothing left to +pipe. Google Cloud Functions and Firebase Functions, for example, expose the +already-read body as `req.rawBody`. Provide a `streamHandler` to feed busboy +yourself in that case: + +```javascript +const upload = multer({ + storage: multer.memoryStorage(), + streamHandler: function (req, busboy) { + if (req.rawBody) { + busboy.end(req.rawBody); + } else { + req.pipe(busboy); + } + }, +}); +``` + +The function receives the request and the busboy instance and must write the +whole multipart body to busboy and end it. + ## Security Specifying the [limits](#limits) can help protect your site against denial of service (DoS) attacks. The following limits are recommended for most applications: @@ -346,16 +397,22 @@ Specifying the [limits](#limits) can help protect your site against denial of se - `files` -- set to the maximum number of files per request - `fields` -- set to the maximum number of text fields per request - `fieldNestingDepth` -- set to the minimum depth your field names require (e.g. `3` for `a[b][c]`) +- `fieldArrayIndexLimit` -- set to the largest array index your field names require (e.g. `100` for `a[99]`) ## エラー処理 -エラーが発生した場合、MulterはエラーをExpressに委任します。 エラーが発生した場合、MulterはエラーをExpressに委任します。 You can +エラーが発生した場合、MulterはエラーをExpressに委任します。エラーが発生した場合、MulterはエラーをExpressに委任します。 You can display a nice error page using [the standard express way](/guide/error-handling). Multer から特にエラーをキャッチしたい場合は、独自に ミドルウェア関数を呼び出すことができます。 Multer から特にエラーをキャッチしたい場合は、独自に ミドルウェア関数を呼び出すことができます。 Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`). +Multer errors carry a `code` (e.g. `LIMIT_FILE_SIZE`) and, when the error concerns +a specific field, its name in `field`. Errors about a specific file +(`LIMIT_FILE_SIZE`, `LIMIT_UNEXPECTED_FILE`) also expose the client-supplied file +name in `filename`; treat it as untrusted input, like `file.originalname`. + ```javascript const multer = require('multer'); const upload = multer().single('avatar'); diff --git a/src/content/pages/ja/resources/middleware/response-time.mdx b/src/content/pages/ja/resources/middleware/response-time.mdx index 0559241876..22df0986ec 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 サーバーの応答時間。 @@ -23,7 +23,7 @@ headers are written out to the client. ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは [`npm install` コマンド](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): diff --git a/src/content/pages/ja/resources/middleware/serve-favicon.mdx b/src/content/pages/ja/resources/middleware/serve-favicon.mdx index 9be737db28..6a03f807eb 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 @@ -38,7 +38,7 @@ HTMLマークアップを必要とする追加のベンダー固有のアイコ ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは [`npm install` コマンド](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): diff --git a/src/content/pages/ja/resources/middleware/serve-index.mdx b/src/content/pages/ja/resources/middleware/serve-index.mdx index cfaac22940..a9f5db4c69 100644 --- a/src/content/pages/ja/resources/middleware/serve-index.mdx +++ b/src/content/pages/ja/resources/middleware/serve-index.mdx @@ -18,7 +18,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは [`npm install` コマンド](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): @@ -54,7 +54,7 @@ Serve indexはoptionsオブジェクトでこれらのプロパティを受け ##### フィルター -このフィルタ機能をファイルに適用します。 デフォルトは `false` です。 このフィルタ機能をファイルに適用します。 デフォルトは `false` です。 The `filter` function +このフィルタ機能をファイルに適用します。 Defaults to `false`. このフィルタ機能をファイルに適用します。 デフォルトは `false` です。 The `filter` function is called for each file, with the signature `filter(filename, index, files, dir)` where `filename` is the name of the file, `index` is the array index, `files` is the array of files and `dir` is the absolute path the file is located (and thus, @@ -62,20 +62,20 @@ the directory the listing is for). ##### hidden -非表示(ドット)ファイルを表示します。 デフォルトは `false` です。 +非表示(ドット)ファイルを表示します。 Defaults to `false`. ##### アイコン -アイコンを表示 デフォルトは `false` です。 +アイコンを表示 Defaults to `false`. ##### stylesheet -CSS スタイルシートへのオプションのパス。 デフォルトはビルトインスタイルシートです。 デフォルトはビルトインスタイルシートです。 +CSS スタイルシートへのオプションのパス。 デフォルトはビルトインスタイルシートです。デフォルトはビルトインスタイルシートです。 ##### テンプレート HTMLテンプレートまたはHTML -文字列をレンダリングする関数への任意のパス。 デフォルトはビルトインテンプレートです。 デフォルトはビルトインテンプレートです。 +文字列をレンダリングする関数への任意のパス。 デフォルトはビルトインテンプレートです。デフォルトはビルトインテンプレートです。 When given a string, the string is used as a file path to load and then the following tokens are replaced in templates: @@ -87,12 +87,12 @@ following tokens are replaced in templates: 関数として与えられた場合、関数は `template(locals, callback)` と呼ばれ、`callback(error, htmlString)` を呼び出す必要があります。 以下はローカルで提供される -です。 以下はローカルで提供される +です。以下はローカルで提供される です。 - `directory`は表示されているディレクトリです(`/`がルートです)。 - `displayIcons` は、アイコンをレンダリングするかどうかを指定するためのブール値です。 -- `fileList` はディレクトリ内のファイルのソートされた配列です。 配列には、以下のプロパティを持つ +- `fileList` はディレクトリ内のファイルのソートされた配列です。配列には、以下のプロパティを持つ オブジェクトが含まれています。 - `name` はファイルの相対的な名前です。 - `stat` はファイルの `fs.Stats` オブジェクトです。 @@ -102,7 +102,7 @@ following tokens are replaced in templates: ##### 表示 -表示モード `tiles`と`details`があります。 表示モード `tiles`と`details`があります。 デフォルトは `tiles` です。 +表示モード `tiles`と`details`があります。表示モード `tiles`と`details`があります。 デフォルトは `tiles` です。 ## 例 @@ -152,8 +152,8 @@ app.listen(3000); ## ライセンス -[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) アイコン -は [FAMFAMFAM](https://web.archive.org/web/20251120154741/http://www.famfamfam.com/) によって作成されます。 +[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). The [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) icons +are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20230109095739/http://www.famfamfam.com/). [appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index [downloads-url]: https://npmjs.org/package/serve-index diff --git a/src/content/pages/ja/resources/middleware/serve-static.mdx b/src/content/pages/ja/resources/middleware/serve-static.mdx index 41f939e7be..04b3528800 100644 --- a/src/content/pages/ja/resources/middleware/serve-static.mdx +++ b/src/content/pages/ja/resources/middleware/serve-static.mdx @@ -9,14 +9,14 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは [`npm install` コマンド](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): @@ -54,12 +54,12 @@ of the `Range` request header. ##### cacheControl `Cache-Control` レスポンスヘッダーの設定を有効または無効にします。デフォルトは -true です。 これを無効にすると、 `immutable` と `maxAge` オプションは無視されます。 +true です。これを無効にすると、 `immutable` と `maxAge` オプションは無視されます。 ##### dotfiles -「dotfiles」が発生したときにどのように扱われるかを設定します。 ドットファイルは、 -またはドット(.)で始まるディレクトリです。 このチェックは、実際にパスが +「dotfiles」が発生したときにどのように扱われるかを設定します。ドットファイルは、 +またはドット(.)で始まるディレクトリです。このチェックは、実際にパスが ディスク上に存在するかどうかをチェックすることなく、 で行われます。 If `root` is specified, only the dotfiles above the root are checked (i.e. the root itself can be within a dotfile when set @@ -77,7 +77,7 @@ etag の生成を有効または無効にします。デフォルトは true で ##### extensions -ファイル拡張子のフォールバックを設定します。 設定すると、ファイルが見つからない場合、指定された +ファイル拡張子のフォールバックを設定します。設定すると、ファイルが見つからない場合、指定された 拡張子がファイル名に追加され、検索されます。 が存在する最初のものが提供されます。 Example: `['html', 'htm']`. @@ -86,10 +86,10 @@ etag の生成を有効または無効にします。デフォルトは true で ##### Fallthrough クライアントエラーが処理されていない -リクエストとしてフォールスルーされるミドルウェアを設定します。そうでなければ、クライアントエラーを転送します。 違いは、悪いリクエストや存在しないファイルへのリクエストなどのクライアント +リクエストとしてフォールスルーされるミドルウェアを設定します。そうでなければ、クライアントエラーを転送します。違いは、悪いリクエストや存在しないファイルへのリクエストなどのクライアント エラーが発生すると、このミドルウェアは 単純に次のミドルウェアに`next()`が発生します。この値は -が`true`の場合。 この値が `false` の場合、これらのエラー (404でさえ) は +が`true`の場合。この値が `false` の場合、これらのエラー (404でさえ) は `next(err)` を呼び出します。 通常、複数の物理ディレクトリが @@ -113,28 +113,28 @@ short-circuiting 404s for less overhead. このミドルウェアは ##### インデックス デフォルトでは、このモジュールはディレクトリのリクエスト -に応答して「index.html」ファイルを送信します。 この設定を無効にするには、`false` または新しいインデックスを提供するには、 +に応答して「index.html」ファイルを送信します。この設定を無効にするには、`false` または新しいインデックスを提供するには、 文字列または配列を優先順位で渡します。 ##### 最終更新日 -`Last-Modified` ヘッダーを有効または無効にします。デフォルトは true です。 ファイル +`Last-Modified` ヘッダーを有効または無効にします。デフォルトは true です。ファイル システムの最後の変更値を使用します。 ##### maxAge -httpキャッシュのために最大年齢をミリ秒単位で指定します。デフォルトは0です。 この +httpキャッシュのために最大年齢をミリ秒単位で指定します。デフォルトは0です。この は [ms](https://www.npmjs.org/package/ms#readme) モジュールで受け付けられる文字列にすることもできます。 ##### リダイレクト -パス名がdirの場合、末尾の"/"にリダイレクトします。 デフォルトは `true` です。 +パス名がdirの場合、末尾の"/"にリダイレクトします。デフォルトは `true` です。 ##### setHeaders -レスポンスにカスタムヘッダーを設定する関数です。 ヘッダへの変更は -で同期的に行われます。 関数は `fn(res, path, stat)` と呼ばれます。引数は +レスポンスにカスタムヘッダーを設定する関数です。ヘッダへの変更は +で同期的に行われます。関数は `fn(res, path, stat)` と呼ばれます。引数は です。 - `res` the response object @@ -227,7 +227,7 @@ app.listen(3000); #### パスの異なる設定 この例では、送信された -ファイルによって異なる最大年齢を設定する方法を示します。 この例では、HTMLファイルはキャッシュされませんが、 +ファイルによって異なる最大年齢を設定する方法を示します。この例では、HTMLファイルはキャッシュされませんが、 はすべて1日間です。 ```js diff --git a/src/content/pages/ja/resources/middleware/session.mdx b/src/content/pages/ja/resources/middleware/session.mdx index 2d14be7543..cbdb381822 100644 --- a/src/content/pages/ja/resources/middleware/session.mdx +++ b/src/content/pages/ja/resources/middleware/session.mdx @@ -16,7 +16,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは [`npm install` コマンド](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): @@ -40,20 +40,19 @@ var session = require('express-session'); 与えられた `options` を使ってセッションミドルウェアを作成します。 **注意** セッションデータはクッキー自体に保存されず、セッションIDだけです。 -セッションデータはサーバーサイドに保存されます。 -セッションデータはサーバーサイドに保存されます。 +セッションデータはサーバーサイドに保存されます。セッションデータはサーバーサイドに保存されます。 **注意** バージョン1.5.0以降、[`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser) はこのモジュールを動作させるために使用する必要がなくなりました。 このモジュールは を直接読み込み、 `req`/`res` に Cookie を書き込みます。 `cookie-parser` を使用すると、このモジュールと `cookie-parser` の間で`secret` が同じでない場合、 -が発生する可能性があります。 このモジュールは +が発生する可能性があります。このモジュールは を直接読み込み、 `req`/`res` に Cookie を書き込みます。 `cookie-parser` を使用すると、このモジュールと `cookie-parser` の間で`secret` が同じでない場合、 が発生する可能性があります。 **警告** デフォルトのサーバーサイドセッションストレージである`MemoryStore`は、_意図的に_ 本番環境用に設計されていません。 ほとんどの 条件下でメモリをリークし、単一のプロセスを経過させることはなく、デバッグと -開発のためのものです。 ほとんどの +開発のためのものです。ほとんどの 条件下でメモリをリークし、単一のプロセスを経過させることはなく、デバッグと 開発のためのものです。 @@ -68,7 +67,7 @@ var session = require('express-session'); Settings object for the session ID cookie. デフォルト値は `{ path: '/', httpOnly: true, secure: false, maxAge: null }` です。 -静的オブジェクトを提供するだけでなく、各リクエストの Cookie オプションを動的に生成するコールバック関数を渡すこともできます。 コールバックは `req` オブジェクトを引数として受け取り、Cookie の設定を含むオブジェクトを返します。 コールバックは `req` オブジェクトを引数として受け取り、Cookie の設定を含むオブジェクトを返します。 +静的オブジェクトを提供するだけでなく、各リクエストの Cookie オプションを動的に生成するコールバック関数を渡すこともできます。 コールバックは `req` オブジェクトを引数として受け取り、Cookie の設定を含むオブジェクトを返します。コールバックは `req` オブジェクトを引数として受け取り、Cookie の設定を含むオブジェクトを返します。 ```js var app = express(); @@ -117,7 +116,7 @@ app.use( `HttpOnly`Set-Cookie`属性の`boolean`値を指定します。 truthyの場合、 `HttpOnly` 属性が設定されています。そうでなければ、そうではありません。 デフォルトでは、`HttpOnly\` 属性が設定されています。 truthyの場合、 -`HttpOnly` 属性が設定されています。そうでなければ、そうではありません。 デフォルトでは、`HttpOnly` +`HttpOnly` 属性が設定されています。そうでなければ、そうではありません。デフォルトでは、`HttpOnly` 属性が設定されています。 **Note** be careful when setting this to `true`, as compliant clients will not allow @@ -128,8 +127,8 @@ client-side JavaScript to see the cookie in `document.cookie`. `Expires` `Set-Cookie` 属性を計算するときに使用する `number` (ミリ秒単位) を指定します。 これは現在のサーバ時間を要し、`Expires`日付を計算するための値に `maxAge`ミリ秒を追加することによって行われます。 デフォルトでは、 -の最大年齢は設定されていません。 これは現在のサーバ時間を要し、`Expires`日付を計算するための値に -`maxAge`ミリ秒を追加することによって行われます。 デフォルトでは、 +の最大年齢は設定されていません。これは現在のサーバ時間を要し、`Expires`日付を計算するための値に +`maxAge`ミリ秒を追加することによって行われます。デフォルトでは、 の最大年齢は設定されていません。 **注意** オプションで `expires` と `maxAge` の両方が設定されている場合、オブジェクトで定義された最後の @@ -137,10 +136,8 @@ client-side JavaScript to see the cookie in `document.cookie`. ##### cookie.partitioned -[`Partitioned` `Set-Cookie`](https://github.com/expressjs/session/blob/HEAD/rfc-cutler-httpbis-partitioned-cookies) -属性の `boolean` 値を指定します。 truthyの場合、`Partitioned` 属性が設定されています。そうでなければ、そうではありません。 -デフォルトでは、 `Partitioned` 属性は設定されていません。 truthyの場合、`Partitioned` 属性が設定されています。そうでなければ、そうではありません。 -デフォルトでは、 `Partitioned` 属性は設定されていません。 +Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`][rfc-cutler-httpbis-partitioned-cookies] +attribute. truthyの場合、`Partitioned` 属性が設定されています。そうでなければ、そうではありません。デフォルトでは、 `Partitioned` 属性は設定されていません。 **Note** This is an attribute that has not yet been fully standardized, and may change in the future. これは、 @@ -151,9 +148,15 @@ More information about can be found in [the proposal](https://github.com/privacy ##### cookie.path `Path` `Set-Cookie` の値を指定します。 デフォルトでは、これは `'/'` に設定されており、ドメインのルートパスは -になります。 デフォルトでは、これは `'/'` に設定されており、ドメインのルートパスは +になります。デフォルトでは、これは `'/'` に設定されており、ドメインのルートパスは になります。 +Since 1.19.1, path matching follows [RFC 6265 section 5.1.4][rfc-6265-5.1.4]. This means +the session middleware will only activate when the request path is an exact match or falls +under a segment boundary of the cookie path. For example, a cookie path of `/admin` will +match `/admin` and `/admin/users` but will **not** match `/administrator`. Prior versions +used a simple prefix check that did not enforce segment boundaries. + ##### cookie.priority [`Priority` `Set-Cookie` 属性][rfc-west-cookie-priority-00-4.1] の値にする文字列を指定します。 @@ -166,14 +169,12 @@ More information about can be found in [the proposal](https://github.com/privacy [仕様][rfc-west-cookie-priority-00-4.1] を参照してください。 **注意** これは完全に標準化されていない属性であり、将来変更される可能性があります。 -これはまた、多くのクライアントがこの属性を理解するまでこの属性を無視することを意味します。 -これはまた、多くのクライアントがこの属性を理解するまでこの属性を無視することを意味します。 +これはまた、多くのクライアントがこの属性を理解するまでこの属性を無視することを意味します。これはまた、多くのクライアントがこの属性を理解するまでこの属性を無視することを意味します。 ##### cookie.sameSite `Set-Cookie`属性の値にする`boolean`または`string`を指定します。 -デフォルトでは `false` です。 -デフォルトでは `false` です。 +デフォルトでは `false` です。デフォルトでは `false` です。 - `true` は、サイトを厳密に強制するために `SameSite` 属性を `Strict` に設定します。 - `false` は `SameSite` 属性を設定しません。 @@ -186,7 +187,7 @@ More information about can be found in [the proposal](https://github.com/privacy [仕様][rfc-6265bis-03-4.1.2.7] を参照してください。 **注意** これは、完全に標準化されていない属性であり、 -将来に変更される可能性があります。 これはまた、多くのクライアントがこの属性を理解するまでこの属性を無視することを意味します。 +将来に変更される可能性があります。これはまた、多くのクライアントがこの属性を理解するまでこの属性を無視することを意味します。 **Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01) that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been @@ -194,8 +195,7 @@ set to `'none'`. 一部のウェブブラウザや他のクライアントがこ The `cookie.sameSite` option can also be set to the special value `'auto'` to have this setting automatically match the determined security of the connection. 接続 -がセキュア(HTTPS)の場合、クロスサイトの使用を可能にするため、`SameSite`属性は`None`に設定されます。 -接続 +がセキュア(HTTPS)の場合、クロスサイトの使用を可能にするため、`SameSite`属性は`None`に設定されます。接続 がセキュア(HTTPS)の場合、クロスサイトの使用を可能にするため、`SameSite`属性は`None`に設定されます。 When the connection is not secure (HTTP), the `SameSite` attribute will be set to `Lax` for better security while maintaining functionality. これは、Express `"Trust proxy"` @@ -207,14 +207,14 @@ SAML認証シナリオを簡素化します。 `Set-Cookie` 属性の `boolean` 値を指定します。 truthyの場合、 `Secure` 属性が設定されています。そうでなければ、そうではありません。 デフォルトでは、`Secure` 属性は設定されていません。 truthyの場合、 -`Secure` 属性が設定されています。そうでなければ、そうではありません。 デフォルトでは、`Secure` +`Secure` 属性が設定されています。そうでなければ、そうではありません。デフォルトでは、`Secure` 属性は設定されていません。 **Note** be careful when setting this to `true`, as compliant clients will not send the cookie back to the server in the future if the browser does not have an HTTPS connection. -`secure: true` は **recommended** オプションです。 ただし、 +`secure: true` は **recommended** オプションです。ただし、 はhttps対応のウェブサイトを必要とします。つまり、HTTPSはセキュアなクッキーに必要です。 `secure` が設定されていて、HTTP経由でサイトにアクセスすると、クッキーは設定されません。 プロキシの後ろに node.js があり、`secure: true` を使用している場合、式で @@ -260,7 +260,7 @@ as once the cookie is set on HTTPS, it will no longer be visible over HTTP. こ ##### genid -新しいセッション ID を生成するために呼び出す関数。 新しいセッション ID を生成するために呼び出す関数。 Provide a function that returns +新しいセッション ID を生成するために呼び出す関数。新しいセッション ID を生成するために呼び出す関数。 Provide a function that returns a string that will be used as a session ID. The function is given `req` as the first argument if you want to use some value attached to `req` when generating the ID. @@ -315,13 +315,13 @@ without a session. デフォルト値は `true` ですが、 のデフォルトが将来変更されるため、デフォルトを使用することは推奨されません。 この設定を調べて、 -あなたのユースケースに適したものを選択してください。 この設定 -を調べて、使用事例に適したものを選んでください。 通常は、 +あなたのユースケースに適したものを選択してください。この設定 +を調べて、使用事例に適したものを選んでください。通常は、 `false` を使用します。 これが自分の店で必要かどうかどうかを知るにはどうすればいいですか? 最良の方法は、`touch`メソッドを実装しているかどうか、店舗で -確認することです。 もしそうであれば、 -は `resave: false` を安全に設定できます。 最良の方法は、`touch`メソッドを実装しているかどうか、店舗で +確認することです。もしそうであれば、 +は `resave: false` を安全に設定できます。最良の方法は、`touch`メソッドを実装しているかどうか、店舗で 確認することです。 もしそうであれば、 は `resave: false` を安全に設定できます。 If it does not implement the `touch` method and your store sets an expiration date on stored sessions, then you @@ -331,7 +331,7 @@ likely need `resave: true`. セッション識別子クッキーをすべてのレスポンスに設定します。 有効期限 は元の[`maxAge`](#cookiemaxage)にリセットされ、有効期限 -カウントダウンをリセットします。 有効期限 +カウントダウンをリセットします。有効期限 は元の[`maxAge`](#cookiemaxage)にリセットされ、有効期限 カウントダウンをリセットします。 @@ -380,11 +380,11 @@ an array of secrets is provided, only the first element will be used to sign the session ID cookie, while all the elements will be considered when verifying the signature in requests. シークレットは、Node.js の `crypto.createHmac` (文字列や `Buffer` のように) でサポートされている値の -型にすることができます。 これは単一のシークレット、または複数のシークレットの配列のいずれかになります。 If +型にすることができます。これは単一のシークレット、または複数のシークレットの配列のいずれかになります。 If an array of secrets is provided, only the first element will be used to sign the session ID cookie, while all the elements will be considered when verifying the signature in requests. シークレット自体は人間によって簡単に解析されるべきではなく、 -はランダムな文字セットであることが最善です。 ベストプラクティスは以下のとおりです: +はランダムな文字セットであることが最善です。ベストプラクティスは以下のとおりです: - シークレットを格納するために環境変数を使用して、シークレット自体 がリポジトリに存在しないことを保証します。 @@ -394,13 +394,13 @@ signature in requests. シークレット自体は人間によって簡単に解 推測できないシークレットを使用すると、セッションを セッションIDを推測するだけのformat@@1にハイジャックすることができなくなります(`genid` オプションで決定されます)。 -シークレットの値を変更すると、既存のすべてのセッションが無効になります。 シークレットの値を変更すると、既存のすべてのセッションが無効になります。 In order to rotate +シークレットの値を変更すると、既存のすべてのセッションが無効になります。シークレットの値を変更すると、既存のすべてのセッションが無効になります。 In order to rotate the secret without invalidating sessions, provide an array of secrets, with the new secret as first element of the array, and including previous secrets as the later elements. **注意** HMAC-256 はセッションIDに署名するために使用されます。 このため、シークレットは -に少なくとも 32 バイトのエントロピーを含める必要があります。 このため、シークレットは +に少なくとも 32 バイトのエントロピーを含める必要があります。このため、シークレットは に少なくとも 32 バイトのエントロピーを含める必要があります。 ##### ストア @@ -422,7 +422,7 @@ elements. セッションデータを保存またはアクセスするには、requestプロパティ`reqを使用します。 ession`, (一般的に) ストアによって JSON としてシリアライズされている ので、入れ子になったオブジェクト -は通常問題ありません。 例えば、以下はユーザー固有のビューカウンターです。 例えば、以下はユーザー固有のビューカウンターです。 +は通常問題ありません。 例えば、以下はユーザー固有のビューカウンターです。例えば、以下はユーザー固有のビューカウンターです。 ```js // Use the session middleware @@ -445,7 +445,7 @@ app.get('/', function (req, res, next) { #### Session.regenerate(callback) -セッションを再生成するには、単にメソッドを呼び出します。 セッションを再生成するには、単にメソッドを呼び出します。 完了すると、 +セッションを再生成するには、単にメソッドを呼び出します。セッションを再生成するには、単にメソッドを呼び出します。 完了すると、 新しいSIDと`Session` インスタンスが`req.session` で初期化され、`callback`が呼び出されます。 @@ -458,8 +458,7 @@ req.session.regenerate(function (err) { #### Session.destroy(callback) セッションを破壊し、`req.session` プロパティを解除します。 -完了すると、`callback` が呼び出されます。 -完了すると、`callback` が呼び出されます。 +完了すると、`callback` が呼び出されます。完了すると、`callback` が呼び出されます。 ```js req.session.destroy(function (err) { @@ -470,7 +469,7 @@ req.session.destroy(function (err) { #### Session.reload(callback) ストアからセッションデータをリロードし、 -`req.session` オブジェクトを再入力します。 完了すると、`callback` が呼び出されます。 完了すると、`callback` が呼び出されます。 +`req.session` オブジェクトを再入力します。 完了すると、`callback` が呼び出されます。完了すると、`callback` が呼び出されます。 ```js req.session.reload(function (err) { @@ -487,7 +486,7 @@ req.session.reload(function (err) { このメソッドは、 セッションデータが変更された場合、HTTPレスポンスの最後に自動的に呼び出されます(ミドルウェアコンストラクタの様々な オプションでこの動作を変更することができます)。 このため、通常、このメソッド -を呼び出す必要はありません。 このため、通常、このメソッド +を呼び出す必要はありません。このため、通常、このメソッド を呼び出す必要はありません。 リダイレクト、長寿命リクエスト、WebSocketなど、このメソッドを呼び出すと便利な場合があります。 @@ -500,19 +499,19 @@ req.session.save(function (err) { #### Session.touch() -`.maxAge` プロパティを更新します。 セッションミドルウェアがこれを行うので、通常はこれは +`.maxAge` プロパティを更新します。セッションミドルウェアがこれを行うので、通常はこれは を呼び出す必要はありません。 ### req.session.id -各セッションには、それに関連付けられた一意のIDがあります。 各セッションには、それに関連付けられた一意のIDがあります。 This property is an +各セッションには、それに関連付けられた一意のIDがあります。各セッションには、それに関連付けられた一意のIDがあります。 This property is an alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified. `session` オブジェクトからセッション ID をアクセス可能にするために追加されました。 ### req.session.cookie -各セッションには、それに付随する固有のクッキーオブジェクトがあります。 各セッションには、それに付随する固有のクッキーオブジェクトがあります。 This allows +各セッションには、それに付随する固有のクッキーオブジェクトがあります。各セッションには、それに付随する固有のクッキーオブジェクトがあります。 This allows you to alter the session cookie per visitor. 例えば、 `req.session.cookie.expires` を `false` に設定すると、ユーザーエージェントの期間のみクッキー を有効にできます。 @@ -522,7 +521,7 @@ you to alter the session cookie per visitor. 例えば、 別の方法として、`req.session.cookie.maxAge`はミリ秒単位の残り時間 を返し、`.expires`プロパティを適切に調整するために新しい値 を再割り当てることもできます。 以下の -は本質的に同等です 以下の +は本質的に同等です以下の は本質的に同等です ```js @@ -549,14 +548,14 @@ req.session.cookie.maxAge; // => 30000 ロードされたセッションの ID を取得するには、request プロパティ `req.sessionID` にアクセスします。 これは、セッション -がロード/作成されたときに読み取り専用の値セットです。 これは、セッション +がロード/作成されたときに読み取り専用の値セットです。これは、セッション がロード/作成されたときに読み取り専用の値セットです。 ## セッションストアの実装 すべてのセッションストア_must_は`EventEmitter`で、特定の メソッドを実装します。 以下のメソッドは、**required**、**recommended**、 -、**optional**のリストです。 以下のメソッドは、**required**、**recommended**、 +、**optional**のリストです。以下のメソッドは、**required**、**recommended**、 、**optional**のリストです。 - 必須メソッドは、このモジュールが常にストアで呼び出すメソッドです。 @@ -606,7 +605,7 @@ ID (`sid`). `callback` は `callback(error, session)` と呼ばれます。 `session` 引数が見つかった場合はセッションを指定します。それ以外の場合は `null` または `undefined` セッションが見つからなかった場合は (エラーがなかった場合) 特別な -の場合は、 `error.code === 'ENOENT'` で `callback(null, null)` のように動作します。 特別な +の場合は、 `error.code === 'ENOENT'` で `callback(null, null)` のように動作します。特別な の場合は、 `error.code === 'ENOENT'` で `callback(null, null)` のように動作します。 ### store.set(sid, session, callback) @@ -874,7 +873,7 @@ based session store. Fortune (ongoDB、Redis、Postgres、NeDB)でサポート [session-file-store-url]: https://www.npmjs.com/package/session-file-store -[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] PouchDB / CouchDB用セッションストア 埋め込み、カスタム、またはリモートPouchDBインスタンスとリアルタイム同期を受け入れます。 埋め込み、カスタム、またはリモートPouchDBインスタンスとリアルタイム同期を受け入れます。 +[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] PouchDB / CouchDB用セッションストア 埋め込み、カスタム、またはリモートPouchDBインスタンスとリアルタイム同期を受け入れます。埋め込み、カスタム、またはリモートPouchDBインスタンスとリアルタイム同期を受け入れます。 [session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store @@ -1040,6 +1039,7 @@ Windows では、対応するコマンドを使用します。 [MIT](https://github.com/expressjs/session/blob/HEAD/LICENSE) +[rfc-6265-5.1.4]: https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 [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-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 diff --git a/src/content/pages/ja/resources/middleware/timeout.mdx b/src/content/pages/ja/resources/middleware/timeout.mdx index 63cce0b77e..56a815b29a 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 @@ -18,7 +18,7 @@ Connect/Expressアプリケーションフレームワークでリクエスト ## インストール これは、 [Node.js](https://nodejs.org/en/) モジュールで、 -[npm registry](https://www.npmjs.com/) を介して利用できます。 インストールは +[npm registry](https://www.npmjs.com/) を介して利用できます。インストールは [`npm install` コマンド](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): @@ -39,8 +39,7 @@ Connect/Expressアプリケーションフレームワークでリクエスト を参照してください。 リクエストが与えられた -タイムアウトを超えた場合、ライブラリは「timeout」イベントを発行しますが、ノードは遅いリクエストを終了するまで処理を続けます。 -タイムアウトコールバックで +タイムアウトを超えた場合、ライブラリは「timeout」イベントを発行しますが、ノードは遅いリクエストを終了するまで処理を続けます。タイムアウトコールバックで HTTP レスポンスを返している場合でも、遅いリクエストは引き続きCPUとメモリを使用します。 For better control over CPU/memory, you may need to find the events that are taking a long time (3rd party HTTP requests, disk I/O, database calls) and find a way to cancel them, and/or @@ -50,7 +49,7 @@ close the attached sockets. `time`ミリ秒でタイムアウトするミドルウェアを返します。 `time` は [ms](https://www.npmjs.org/package/ms#readme) -モジュールで受け付ける文字列にすることもできます。 タイムアウト時に、 `req` は `"timeout"`を出力します。 +モジュールで受け付ける文字列にすることもできます。タイムアウト時に、 `req` は `"timeout"`を出力します。 #### オプション @@ -61,8 +60,8 @@ any of the following keys: このモジュールがエラーを転送する形で「応答」するかどうかを制御します。 `true` の場合、レスポンスの動作を -カスタマイズできるように、タイムアウトエラーが `next()` に渡されます。 このエラーは `.timeout` プロパティと -`.status == 503` を持ちます。 このデフォルトは `true` です。 +カスタマイズできるように、タイムアウトエラーが `next()` に渡されます。このエラーは `.timeout` プロパティと +`.status == 503` を持ちます。このデフォルトは `true` です。 ### req.clearTimeout() diff --git a/src/content/pages/ja/resources/middleware/vhost.mdx b/src/content/pages/ja/resources/middleware/vhost.mdx index 55303ce24d..d43207f67e 100644 --- a/src/content/pages/ja/resources/middleware/vhost.mdx +++ b/src/content/pages/ja/resources/middleware/vhost.mdx @@ -34,7 +34,7 @@ var vhost = require('vhost'); ### vhost(hostname, handle) リクエストの -ホストが`hostname`と一致する場合、`handle`にリクエストを渡すための新しいミドルウェア関数を作成します。 関数は、標準のミドルウェアのように、 +ホストが`hostname`と一致する場合、`handle`にリクエストを渡すための新しいミドルウェア関数を作成します。関数は、標準のミドルウェアのように、 `handle(req, res, next)`と呼ばれます。 `hostname`は文字列またはRegExpオブジェクトを使用できます。 When `hostname` is a string it can @@ -43,7 +43,7 @@ contain `*` to match 1 or more characters in that section of the hostname. When and will be forced to match based on the start and end of the hostname. ホストが一致し、リクエストが vhost ハンドラに送信されると、`req.vhost` -プロパティにオブジェクトが入力されます。 このオブジェクトには、各ワイルドカードに対応する数値プロパティ +プロパティにオブジェクトが入力されます。このオブジェクトには、各ワイルドカードに対応する数値プロパティ があります(RegExp オブジェクトが指定されている場合はグループをキャプチャします)。 `hostname` に一致します。 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 9b405a9d94..8135fd41bf 100644 --- a/src/content/pages/ko/advanced/best-practice-security.mdx +++ b/src/content/pages/ko/advanced/best-practice-security.mdx @@ -48,7 +48,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) { @@ -269,7 +269,7 @@ $ npm audit If you want to stay more secure, consider [Snyk](https://snyk.io/). -Snyk offers both a [command-line tool](https://www.npmjs.com/package/snyk) and a [Github integration](https://snyk.io/docs/github) that checks your application against [Snyk's open source vulnerability database](https://snyk.io/vuln/) for any known vulnerabilities in your dependencies. Install the CLI as follows: +Snyk offers both a [command-line tool](https://www.npmjs.com/package/snyk) and a [Github integration](https://docs.snyk.io/discover-snyk/getting-started) that checks your application against [Snyk's open source vulnerability database](https://security.snyk.io/) for any known vulnerabilities in your dependencies. Install the CLI as follows: ```bash $ npm install -g snyk @@ -286,7 +286,7 @@ $ snyk test Keep an eye out for [GitHub Advisory Database](https://github.com/advisories?query=ecosystem%3Anpm) or [Snyk](https://security.snyk.io/vuln/npm) advisories that may affect Express or other modules that your app uses. In general, these databases are excellent resources for knowledge and tools about Node security. -Finally, Express apps—like any other web apps—can be vulnerable to a variety of web-based attacks. Familiarize yourself with known [web vulnerabilities](https://www.owasp.org/www-project-top-ten/) and take precautions to avoid them. +Finally, Express apps—like any other web apps—can be vulnerable to a variety of web-based attacks. Familiarize yourself with known [web vulnerabilities](https://owasp.org/www-project-top-ten/) and take precautions to avoid them. ## Additional considerations @@ -294,8 +294,8 @@ Here are some further recommendations from the excellent [Node.js Security Check - Always filter and sanitize user input to protect against cross-site scripting (XSS) and command injection attacks. - Defend against SQL injection attacks by using parameterized queries or prepared statements. -- Use the open-source [sqlmap](http://sqlmap.org/) tool to detect SQL injection vulnerabilities in your app. +- Use the open-source [sqlmap](https://sqlmap.org/) tool to detect SQL injection vulnerabilities in your app. - Use the [nmap](https://nmap.org/) and [sslyze](https://github.com/nabla-c0d3/sslyze) tools to test the configuration of your SSL ciphers, keys, and renegotiation as well as the validity of your certificate. -- Use [safe-regex](https://www.npmjs.com/package/safe-regex) to ensure your regular expressions are not susceptible to [regular expression denial of service](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) attacks. +- Use [safe-regex](https://www.npmjs.com/package/safe-regex) to ensure your regular expressions are not susceptible to [regular expression denial of service](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) attacks. -[helmet]: https://helmetjs.github.io/ +[helmet]: https://helmet.js.org/ 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/guide/migrating-4.mdx b/src/content/pages/ko/guide/migrating-4.mdx index acd2fb1488..c27097bb43 100644 --- a/src/content/pages/ko/guide/migrating-4.mdx +++ b/src/content/pages/ko/guide/migrating-4.mdx @@ -43,133 +43,23 @@ middleware that is required to run your app. Simply follow these steps: The following table lists Express 3 middleware and their counterparts in Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Express 3Express 4
- express.bodyParser - - body-parser + - multer -
- express.compress - - compression -
- express.cookieSession - - cookie-session -
- express.cookieParser - - cookie-parser -
- express.logger - - morgan -
- express.session - - express-session -
- express.favicon - - serve-favicon -
- express.responseTime - - response-time -
- express.errorHandler - - errorhandler -
- express.methodOverride - - method-override -
- express.timeout - - connect-timeout -
- express.vhost - - vhost -
- express.csrf - - csurf -
- express.directory - - serve-index -
- express.static - - serve-static -
+| Express 3 | Express 4 | +| ------------------------ | ------------------------------------------------------------------------------------------------------- | +| `express.bodyParser` | [body-parser](https://github.com/expressjs/body-parser) + [multer](https://github.com/expressjs/multer) | +| `express.compress` | [compression](https://github.com/expressjs/compression) | +| `express.cookieSession` | [cookie-session](https://github.com/expressjs/cookie-session) | +| `express.cookieParser` | [cookie-parser](https://github.com/expressjs/cookie-parser) | +| `express.logger` | [morgan](https://github.com/expressjs/morgan) | +| `express.session` | [express-session](https://github.com/expressjs/session) | +| `express.favicon` | [serve-favicon](https://github.com/expressjs/serve-favicon) | +| `express.responseTime` | [response-time](https://github.com/expressjs/response-time) | +| `express.errorHandler` | [errorhandler](https://github.com/expressjs/errorhandler) | +| `express.methodOverride` | [method-override](https://github.com/expressjs/method-override) | +| `express.timeout` | [connect-timeout](https://github.com/expressjs/timeout) | +| `express.vhost` | [vhost](https://github.com/expressjs/vhost) | +| `express.csrf` | [csurf](https://github.com/expressjs/csurf) | +| `express.directory` | [serve-index](https://github.com/expressjs/serve-index) | +| `express.static` | [serve-static](https://github.com/expressjs/serve-static) | Here is the [complete list](https://github.com/senchalabs/connect#middleware) of Express 4 middleware. @@ -305,78 +195,21 @@ middleware that is specific to the route. The following table lists other small but important changes in Express 4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ObjectDescription
Node.jsExpress 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x.
`http.createServer()` - The `http` module is no longer needed, unless you need to directly work with it - (socket.io/SPDY/HTTPS). The app can be started by using the `app.listen()` function. -
`app.configure()` - The `app.configure()` function has been removed. Use the `process.env.NODE_ENV` or - `app.get('env')` function to detect the environment and configure the app accordingly. -
`json spaces` - The `json spaces` application property is disabled by default in Express 4. -
`req.accepted()` - Use `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, and - `req.acceptsLanguages()`. -
`res.location()`No longer resolves relative URLs.
`req.params`Was an array; now an object.
`res.locals`Was a function; now an object.
`res.headerSent`Changed to `res.headersSent`.
`app.route`Now available as `app.mountpath`.
`res.on('header')`Removed.
`res.charset`Removed.
`res.setHeader('Set-Cookie', val)` - Functionality is now limited to setting the basic cookie value. Use `res.cookie()` for added - functionality. -
+| Object | Description | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Node.js | Express 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x. | +| `http.createServer()` | The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). The app can be started by using the `app.listen()` function. | +| `app.configure()` | The `app.configure()` function has been removed. Use the `process.env.NODE_ENV` or `app.get('env')` function to detect the environment and configure the app accordingly. | +| `json spaces` | The `json spaces` application property is disabled by default in Express 4. | +| `req.accepted()` | Use `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, and `req.acceptsLanguages()`. | +| `res.location()` | No longer resolves relative URLs. | +| `req.params` | Was an array; now an object. | +| `res.locals` | Was a function; now an object. | +| `res.headerSent` | Changed to `res.headersSent`. | +| `app.route` | Now available as `app.mountpath`. | +| `res.on('header')` | Removed. | +| `res.charset` | Removed. | +| `res.setHeader('Set-Cookie', val)` | Functionality is now limited to setting the basic cookie value. Use `res.cookie()` for added functionality. | ## Example app migration diff --git a/src/content/pages/ko/resources/middleware/body-parser.mdx b/src/content/pages/ko/resources/middleware/body-parser.mdx index eec2e8a5d2..3547c52f26 100644 --- a/src/content/pages/ko/resources/middleware/body-parser.mdx +++ b/src/content/pages/ko/resources/middleware/body-parser.mdx @@ -44,6 +44,10 @@ This module provides the following parsers: - [Text body parser](#bodyparsertextoptions) - [URL-encoded form body parser](#bodyparserurlencodedoptions) +All parsers support automatic inflation of `gzip`, `br` (brotli), `deflate` +and `zstd` encodings. `zstd` is available in Node.js `^22.15.0` and +`>=23.8.0`. + Other body parsers you might be interested in: - [body](https://www.npmjs.com/package/body#readme) @@ -85,8 +89,7 @@ The various errors returned by this module are described in the Returns middleware that only parses `json` and only looks at requests where the `Content-Type` header matches the `type` option. This parser accepts any -Unicode encoding of the body and supports automatic inflation of `gzip`, -`br` (brotli) and `deflate` encodings. +Unicode encoding of the body. A new `body` object containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). @@ -146,9 +149,7 @@ encoding of the request. The parsing can be aborted by throwing an error. ### bodyParser.raw([options]) Returns middleware that parses all bodies as a `Buffer` and only looks at -requests where the `Content-Type` header matches the `type` option. This -parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate` -encodings. +requests where the `Content-Type` header matches the `type` option. A new `body` object containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). This will be a `Buffer` object @@ -194,9 +195,7 @@ encoding of the request. The parsing can be aborted by throwing an error. ### bodyParser.text([options]) Returns middleware that parses all bodies as a string and only looks at -requests where the `Content-Type` header matches the `type` option. This -parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate` -encodings. +requests where the `Content-Type` header matches the `type` option. A new `body` string containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). This will be a string of the @@ -247,8 +246,7 @@ encoding of the request. The parsing can be aborted by throwing an error. Returns middleware that only parses `urlencoded` bodies and only looks at requests where the `Content-Type` header matches the `type` option. This -parser accepts only UTF-8 and ISO-8859-1 encodings of the body and supports -automatic inflation of `gzip`, `br` (brotli) and `deflate` encodings. +parser accepts only UTF-8 and ISO-8859-1 encodings of the body. A new `body` object containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). This object will contain @@ -358,7 +356,7 @@ the entity value that failed parsing. ### entity verify failed This error will occur when the request contained an entity that could not be -failed verification by the defined `verify` option. The `status` property is +verified by the defined `verify` option. The `status` property is set to `403`, the `type` property is set to `'entity.verify.failed'`, and the `body` property is set to the entity value that failed verification. diff --git a/src/content/pages/ko/resources/middleware/compression.mdx b/src/content/pages/ko/resources/middleware/compression.mdx index 162d32c2c2..be10551790 100644 --- a/src/content/pages/ko/resources/middleware/compression.mdx +++ b/src/content/pages/ko/resources/middleware/compression.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -21,13 +21,13 @@ The following compression codings are supported: - gzip - br (brotli) -**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0. +**Note** Brotli is available in all currently supported Node.js LTS versions (v18+). ## Install This is a [Node.js](https://nodejs.org/en/) module available through the [npm registry](https://www.npmjs.com/). Installation is done using the -[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): +[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally): @@ -304,7 +304,7 @@ The Express.js project welcomes all constructive contributions. Contributions ta from code for bug fixes and enhancements, to additions and fixes to documentation, additional tests, triaging incoming pull requests and issues, and more! -See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing. +See the [Contributing Guide](https://github.com/expressjs/.github/blob/HEAD/CONTRIBUTING.md) for more technical details on contributing. ## License diff --git a/src/content/pages/ko/resources/middleware/cookie-session.mdx b/src/content/pages/ko/resources/middleware/cookie-session.mdx index d9db6b0052..d250082180 100644 --- a/src/content/pages/ko/resources/middleware/cookie-session.mdx +++ b/src/content/pages/ko/resources/middleware/cookie-session.mdx @@ -124,7 +124,7 @@ The options can also contain any of the following (for the full list, see - `partitioned`: a boolean indicating whether to partition the cookie in Chrome for the [CHIPS Update](https://developers.google.com/privacy-sandbox/3pcd/chips) (`false` by default). If this is true, Cookies from embedded sites will be partitioned and only readable from the same top level site from which it was created. - `priority`: a string indicating the cookie priority. This can be set to `'low'`, `'medium'`, or `'high'`. - `sameSite`: a boolean or string indicating whether the cookie is a "same site" cookie (`false` by default). This can be set to `'strict'`, `'lax'`, `'none'`, or `true` (which maps to `'strict'`). -- `secure`: a boolean indicating whether the cookie is only to be sent over HTTPS (`false` by default for HTTP, `true` by default for HTTPS). If this is set to `true` and Node.js is not directly over a TLS connection, be sure to read how to [setup Express behind proxies](/guide/behind-proxies) or the cookie may not ever set correctly. +- `secure`: a boolean indicating whether the cookie is only to be sent over HTTPS (`false` by default for HTTP, `true` by default for HTTPS). If this is set to `true` and Node.js is not directly over a TLS connection, be sure to read how to [setup Express behind proxies](/guide/behind-proxies/) or the cookie may not ever set correctly. - `httpOnly`: a boolean indicating whether the cookie is only to be sent over HTTP(S), and not made available to client JavaScript (`true` by default). - `signed`: a boolean indicating whether the cookie is to be signed (`true` by default). - `overwrite`: a boolean indicating whether to overwrite previously set cookies of the same name (`true` by default). diff --git a/src/content/pages/ko/resources/middleware/morgan.mdx b/src/content/pages/ko/resources/middleware/morgan.mdx index bbf752df98..d4cffce323 100644 --- a/src/content/pages/ko/resources/middleware/morgan.mdx +++ b/src/content/pages/ko/resources/middleware/morgan.mdx @@ -8,14 +8,14 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; HTTP request logger middleware for node.js -> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. +> Named after [Dexter](https://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. ## Installation @@ -35,6 +35,16 @@ This is a [Node.js](https://nodejs.org/en/) module available through the ## API +For ES Modules: + +{/* eslint-disable no-unused-vars */} + +```js +import morgan from 'morgan'; +``` + +For CommonJS: + {/* eslint-disable no-unused-vars */} ```js @@ -78,10 +88,12 @@ morgan(function (tokens, req, res) { tokens.method(req, res), tokens.url(req, res), tokens.status(req, res), - tokens.res(req, res, 'content-length'), '-', - tokens['response-time'](https://github.com/expressjs/morgan/blob/HEAD/req, res), 'ms' - ].join(' ') -}) + tokens.res(req, res, 'content-length'), + '-', + tokens['response-time'](req, res), + 'ms', + ].join(' '); +}); ``` #### Options @@ -90,7 +102,7 @@ Morgan accepts these properties in the options object. ##### immediate -Write log line on request instead of response. This means that a requests will +Write log line on request instead of response. This means that requests will be logged even if the server crashes, _but data from the response (like the response code, content length, etc.) cannot be logged_. @@ -114,6 +126,33 @@ morgan('combined', { Output stream for writing log lines, defaults to `process.stdout`. +If the stream is in object mode (`stream.writableObjectMode` is `true`) and the +format function returns an object, the object is written to the stream as-is, +without a trailing newline. This allows passing structured log entries to +loggers that accept objects: + +{/* eslint-disable no-undef */} + +```js +morgan( + function (tokens, req, res) { + return { + method: tokens.method(req, res), + url: tokens.url(req, res), + status: Number(tokens.status(req, res)), + }; + }, + { + stream: { + writableObjectMode: true, + write: function (entry) { + // entry is the object returned by the format function + }, + }, + } +); +``` + #### Predefined Formats There are various pre-defined formats provided: @@ -151,6 +190,11 @@ for information codes. GET /dev 200 0.224 ms - 2 ``` +Coloring is disabled when the [`NO_COLOR`](https://no-color.org) environment +variable is set to any non-empty value, in which case the output above is +written without any escape sequences. The variable is read once, when `morgan` +is first required. + ##### short Shorter than default, also including response time. @@ -192,7 +236,7 @@ token definition. The token function is expected to be called with the arguments `req` and `res`, representing the HTTP request and HTTP response. Additionally, the token can accept further arguments of -it's choosing to customize behavior. +its choosing to customize behavior. ##### :date[format] @@ -218,7 +262,7 @@ The process ID of the Node.js process handling the request. ##### -The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer. +The Referrer header of the request. This will use the standard mis-spelled Referer header if it exists, otherwise Referrer. ##### :remote-addr @@ -264,7 +308,7 @@ include on the number, defaulting to `3`, which provides microsecond precision. ##### -The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`. +The URL of the request. This will use `req.originalUrl` if it exists, otherwise `req.url`. ##### :user-agent @@ -274,12 +318,12 @@ The contents of the User-Agent header of the request. Compile a format string into a `format` function for use by `morgan`. A format string is a string that represents a single log line and can utilize token syntax. -Tokens are references by `:token-name`. If tokens accept arguments, they can +Tokens are referenced by `:token-name`. If tokens accept arguments, they can be passed using `[]`, for example: `:token-name[pretty]` would pass the string `'pretty'` as an argument to the token `token-name`. The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and -`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and +`res`, where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res` is the HTTP response. The function will return a string that will be the log line, or `undefined` / `null` to skip logging. @@ -290,7 +334,7 @@ advanced uses, this compile function is directly available. ### express/connect -Sample app that will log all request in the Apache combined format to STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var express = require('express'); @@ -307,7 +351,7 @@ app.get('/', function (req, res) { ### vanilla http server -Sample app that will log all request in the Apache combined format to STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var finalhandler = require('finalhandler'); @@ -431,7 +475,7 @@ Sample app that will use custom token formats. This adds an ID to all requests a ```js var express = require('express'); var morgan = require('morgan'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); morgan.token('id', function getId(req) { return req.id; diff --git a/src/content/pages/ko/resources/middleware/multer.mdx b/src/content/pages/ko/resources/middleware/multer.mdx index f4c9dd14fb..d32246802f 100644 --- a/src/content/pages/ko/resources/middleware/multer.mdx +++ b/src/content/pages/ko/resources/middleware/multer.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -18,23 +18,6 @@ on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency. **NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`). -## Translations - -This README is also available in other languages: - -| | | -| ------------------------------------------------------------------------------ | --------------- | -| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic | -| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese | -| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French | -| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean | -| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) | -| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian | -| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish | -| [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) | Turkish | - ## Installation @@ -130,23 +113,26 @@ app.post('/stats', upload.single('uploaded_file'), function (req, res) { }); ``` +Complete client-side and server-side examples (browser `FormData` uploads of a +blob and of an image) are in the [`examples/`](https://github.com/expressjs/multer/blob/HEAD/examples/) folder. + ## API ### File information Each file contains the following information: -| Key | Description | Note | -| -------------- | --------------------------------------------- | --------------- | -| `fieldname` | Field name specified in the form | | -| `originalname` | Name of the file on the user's computer | | -| `encoding` | Encoding type of the file | | -| `mimetype` | Mime type of the file | | -| `size` | Size of the file in bytes | | -| `destination` | The folder to which the file has been saved | `DiskStorage` | -| `filename` | The name of the file within the `destination` | `DiskStorage` | -| `path` | The full path to the uploaded file | `DiskStorage` | -| `buffer` | A `Buffer` of the entire file | `MemoryStorage` | +| Key | Description | Note | +| -------------- | ----------------------------------------------------------------------------------- | --------------- | +| `fieldname` | Field name specified in the form | | +| `originalname` | Name of the file on the user's computer, or the full path when `preservePath: true` | | +| `encoding` | Encoding type of the file | | +| `mimetype` | Mime type of the file | | +| `size` | Size of the file in bytes | | +| `destination` | The folder to which the file has been saved | `DiskStorage` | +| `filename` | The name of the file within the `destination` | `DiskStorage` | +| `path` | The full path to the uploaded file | `DiskStorage` | +| `buffer` | A `Buffer` of the entire file | `MemoryStorage` | ### `multer(opts)` @@ -161,11 +147,15 @@ The following are the options that can be passed to Multer. | Key | Description | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `defCharset` | Default character set to use for text field values that do not declare one. Default: `'utf8'` | +| `defParamCharset` | Default character set to use for values of part header parameters (e.g. filename) that are not extended parameters (that contain an explicit charset). Default: `'latin1'` | | `dest` or `storage` | Where to store the files | | `fileFilter` | Function to control which files are accepted | +| `fileHwm` | `highWaterMark` of each file stream (`file.stream`). Default: busboy's default | +| `highWaterMark` | `highWaterMark` of the multipart parser stream. Default: busboy's default | | `limits` | Limits of the uploaded data | -| `preservePath` | Keep the full path of files instead of just the base name | -| `defParamCharset` | Default character set to use for values of part header parameters (e.g. filename) that are not extended parameters (that contain an explicit charset). Default: `'latin1'` | +| `preservePath` | Keep the full client-supplied path in `file.originalname` instead of just the base name | +| `streamHandler` | Function that feeds the request body to busboy; defaults to `req.pipe(busboy)` | In an average web app, only `dest` might be required, and configured as shown in the following example. @@ -174,6 +164,14 @@ the following example. const upload = multer({ dest: 'uploads/' }); ``` +When `preservePath` is enabled, Multer passes the incoming filename through with +any path segments provided by the client. This is exposed as `file.originalname`; +it does not change the destination folder, create directories, or sanitize the +path for you. `file.originalname` is always client-supplied and should be treated +as untrusted; with `preservePath` it additionally contains the path segments the +client sent. Normalize or validate it before using it in a custom `filename` or +storage engine. + If you want more control over your uploads, you'll want to use the `storage` option instead of `dest`. Multer ships with storage engines `DiskStorage` and `MemoryStorage`; More engines are available from third parties. @@ -189,6 +187,9 @@ Accept an array of files, all with the name `fieldname`. Optionally error out if more than `maxCount` files are uploaded. The array of files will be stored in `req.files`. +Files skipped by `fileFilter` do not count towards `maxCount`. Use +`limits.files` to bound how many files are read from a request. + #### `.fields(fields)` Accept a mix of files, specified by `fields`. An object with arrays of files @@ -207,11 +208,11 @@ Example: #### `.none()` Accept only text fields. If any file upload is made, error with code -"LIMIT_UNEXPECTED_FILE" will be issued. +`LIMIT_UNEXPECTED_FILE` will be issued. #### `.any()` -Accepts all files that comes over the wire. An array of files will be stored in +Accepts all files that come over the wire. An array of files will be stored in `req.files`. **WARNING:** Make sure that you always handle the files that a user uploads. @@ -226,21 +227,26 @@ where you are handling the uploaded files. The disk storage engine gives you full control on storing files to disk. ```javascript +const crypto = require('crypto'); + const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/tmp/my-uploads'); }, filename: function (req, file, cb) { - const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); - cb(null, file.fieldname + '-' + uniqueSuffix); + crypto.randomBytes(16, function (err, raw) { + if (err) return cb(err); + cb(null, file.fieldname + '-' + raw.toString('hex')); + }); }, }); const upload = multer({ storage: storage }); ``` -There are two options available, `destination` and `filename`. They are both -functions that determine where the file should be stored. +There are three options available: `destination`, `filename` and `flush`. All of +them except `flush` are functions that determine where the file should be +stored. `destination` is used to determine within which folder the uploaded files should be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no @@ -268,6 +274,14 @@ For understanding the calling convention used in the callback (needing to pass null as the first param), refer to [Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors) +`flush` is an optional boolean. When set to `true`, the file data is flushed to +disk with an `fsync` call before the upload handler runs, which prevents data +loss if the process or the system crashes while the data is still sitting in +the operating system's page cache. It is disabled by default because forcing a +disk flush on every upload has a performance cost. Note that this syncs the +file contents only; if the new directory entry must survive a crash as well, +fsync the destination directory yourself. + #### `MemoryStorage` The memory storage engine stores the files in memory as `Buffer` objects. It @@ -287,20 +301,36 @@ memory storage is used. ### `limits` -An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods). +An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#exports). + +`limits` can also be a function that receives the request and returns such an +object. It is called once per request, before parsing starts, so limits can +depend on e.g. the authenticated user: + +```javascript +const upload = multer({ + limits: function (req) { + return { fileSize: req.user.maxUploadSize }; + }, +}); +``` + +Limits apply to the whole request; there is no per-file limit. To restrict +individual files by type or name, use `fileFilter` or a custom storage engine. The following integer values are available: -| Key | Description | Default | -| ------------------- | -------------------------------------------------------------------------- | --------- | -| `fieldNameSize` | Max field name size | 100 bytes | -| `fieldSize` | Max field value size (in bytes) | 1MB | -| `fields` | Max number of non-file fields | Infinity | -| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity | -| `files` | For multipart forms, the max number of file fields | Infinity | -| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity | -| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 | -| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinity | +| Key | Description | Default | +| ---------------------- | ------------------------------------------------------------------------------- | -------- | +| `fieldNameSize` | Max field name size | Infinity | +| `fieldSize` | Max field value size (in bytes) | 1MB | +| `fields` | Max number of non-file fields | Infinity | +| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity | +| `files` | For multipart forms, the max number of file fields | Infinity | +| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity | +| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 | +| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinity | +| `fieldArrayIndexLimit` | Max numeric array index accepted inside a field name (e.g. `a[3]` uses index 3) | Infinity | Specifying the limits can help protect your site against denial of service (DoS) attacks. @@ -325,6 +355,30 @@ function fileFilter(req, file, cb) { } ``` +### `streamHandler` + +By default Multer reads the request with `req.pipe(busboy)`. Some platforms +consume the request body before your handlers run, so there is nothing left to +pipe. Google Cloud Functions and Firebase Functions, for example, expose the +already-read body as `req.rawBody`. Provide a `streamHandler` to feed busboy +yourself in that case: + +```javascript +const upload = multer({ + storage: multer.memoryStorage(), + streamHandler: function (req, busboy) { + if (req.rawBody) { + busboy.end(req.rawBody); + } else { + req.pipe(busboy); + } + }, +}); +``` + +The function receives the request and the busboy instance and must write the +whole multipart body to busboy and end it. + ## Security Specifying the [limits](#limits) can help protect your site against denial of service (DoS) attacks. The following limits are recommended for most applications: @@ -333,15 +387,21 @@ Specifying the [limits](#limits) can help protect your site against denial of se - `files` -- set to the maximum number of files per request - `fields` -- set to the maximum number of text fields per request - `fieldNestingDepth` -- set to the minimum depth your field names require (e.g. `3` for `a[b][c]`) +- `fieldArrayIndexLimit` -- set to the largest array index your field names require (e.g. `100` for `a[99]`) ## Error handling When encountering an error, Multer will delegate the error to Express. You can -display a nice error page using [the standard express way](/guide/error-handling). +display a nice error page using [the standard express way](/guide/error-handling/). If you want to catch errors specifically from Multer, you can call the middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`). +Multer errors carry a `code` (e.g. `LIMIT_FILE_SIZE`) and, when the error concerns +a specific field, its name in `field`. Errors about a specific file +(`LIMIT_FILE_SIZE`, `LIMIT_UNEXPECTED_FILE`) also expose the client-supplied file +name in `filename`; treat it as untrusted input, like `file.originalname`. + ```javascript const multer = require('multer'); const upload = multer().single('avatar'); diff --git a/src/content/pages/ko/resources/middleware/serve-index.mdx b/src/content/pages/ko/resources/middleware/serve-index.mdx index 7b556879de..b96ac28c4e 100644 --- a/src/content/pages/ko/resources/middleware/serve-index.mdx +++ b/src/content/pages/ko/resources/middleware/serve-index.mdx @@ -39,7 +39,7 @@ var serveIndex = require('serve-index'); ### serveIndex(path, options) -Returns middlware that serves an index of the directory in the given `path`. +Returns middleware that serves an index of the directory in the given `path`. The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir` with a `path` of `'public'` will look at `'public/some/dir'`. If you are using @@ -150,7 +150,7 @@ app.listen(3000); ## License [MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). The [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) icons -are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20251120154741/http://www.famfamfam.com/). +are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20230109095739/http://www.famfamfam.com/). [appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index [downloads-url]: https://npmjs.org/package/serve-index diff --git a/src/content/pages/ko/resources/middleware/session.mdx b/src/content/pages/ko/resources/middleware/session.mdx index 63dd4cb09a..73ac7d1ee0 100644 --- a/src/content/pages/ko/resources/middleware/session.mdx +++ b/src/content/pages/ko/resources/middleware/session.mdx @@ -127,7 +127,7 @@ defined in the object is what is used. ##### cookie.partitioned -Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](https://github.com/expressjs/session/blob/HEAD/rfc-cutler-httpbis-partitioned-cookies) +Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`][rfc-cutler-httpbis-partitioned-cookies] attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not. By default, the `Partitioned` attribute is not set. @@ -142,6 +142,12 @@ More information about can be found in [the proposal](https://github.com/privacy Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which is the root path of the domain. +Since 1.19.1, path matching follows [RFC 6265 section 5.1.4][rfc-6265-5.1.4]. This means +the session middleware will only activate when the request path is an exact match or falls +under a segment boundary of the cookie path. For example, a cookie path of `/admin` will +match `/admin` and `/admin/users` but will **not** match `/administrator`. Prior versions +used a simple prefix check that did not enforce segment boundaries. + ##### cookie.priority Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1]. @@ -1002,6 +1008,7 @@ On Windows, use the corresponding command; [MIT](https://github.com/expressjs/session/blob/HEAD/LICENSE) +[rfc-6265-5.1.4]: https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 [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-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 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 24adb4c5cb..136ce231c3 100644 --- a/src/content/pages/pt-br/advanced/best-practice-security.mdx +++ b/src/content/pages/pt-br/advanced/best-practice-security.mdx @@ -48,7 +48,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) { @@ -269,7 +269,7 @@ $ npm audit Se você deseja ficar mais seguro, considere [Snyk](https://snyk.io/). -Snyk oferece tanto uma [ferramenta de linha de comando](https://www.npmjs.com/package/snyk) quanto uma [integração com um Github](https://snyk.io/docs/github) que verifica a sua aplicação no [banco de dados de vulnerabilidades de fonte aberta do Snyk](https://snyk.io/vuln/) para quaisquer vulnerabilidades conhecidas em suas dependências. Instalar CLI da seguinte forma: +Snyk oferece tanto uma [ferramenta de linha de comando](https://www.npmjs.com/package/snyk) quanto uma [integração com um Github](https://docs.snyk.io/discover-snyk/getting-started) que verifica a sua aplicação no [banco de dados de vulnerabilidades de fonte aberta do Snyk](https://security.snyk.io/) para quaisquer vulnerabilidades conhecidas em suas dependências. Instalar CLI da seguinte forma: ```bash $ npm install -g snyk @@ -294,8 +294,8 @@ Aqui estão mais algumas recomendações do excelente [Checklist de Segurança d - Sempre filtre e sanize a entrada do usuário para proteger contra scripts entre sites (XSS) e ataques de injeção de comando. - Defenda-se contra ataques de injeção de SQL usando consultas parametrizadas ou declarações preparadas. -- Use a ferramenta de código aberto [sqlmap](http://sqlmap.org/) para detectar as vulnerabilidades de injeção de SQL em seu aplicativo. +- Use a ferramenta de código aberto [sqlmap](https://sqlmap.org/) para detectar as vulnerabilidades de injeção de SQL em seu aplicativo. - Usar as ferramentas [nmap](https://nmap.org/) e [sslyze](https://github.com/nabla-c0d3/sslyze) para testar a configuração de suas cifras SSL, chaves e renegociação, bem como a validade de seu certificado. -- Use [safe-regex](https://www.npmjs.com/package/safe-regex) para garantir que suas expressões regulares não são suscetíveis a ataques [negação regular de serviço](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). +- Use [safe-regex](https://www.npmjs.com/package/safe-regex) para garantir que suas expressões regulares não são suscetíveis a ataques [negação regular de serviço](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS). -[helmet]: https://helmetjs.github.io/ +[helmet]: https://helmet.js.org/ 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/guide/migrating-4.mdx b/src/content/pages/pt-br/guide/migrating-4.mdx index 203ac74cd2..b8cab69f2e 100644 --- a/src/content/pages/pt-br/guide/migrating-4.mdx +++ b/src/content/pages/pt-br/guide/migrating-4.mdx @@ -43,133 +43,23 @@ que é necessário para executar seu aplicativo. Basta seguir estes passos: A seguinte tabela lista Express 3 middleware e seus homólogos no Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expressar 3Express 4
- express.bodyParser - - body-parser + - multer -
- express.compress - - compressão -
- express.cookieSession - - Ucookie-session -
- express.cookieParser - - cookie-parser -
- express.logger - - Morgan -
- Uexpressão.sessão - - express-session -
- express.favicon - - serve-favicon -
- express.responseTime - - response-time -
- express.errorHandler - - errorhandler -
- express.methodOverride - - method-override -
- express.timeout - - connect-timeout -
- express.vhost - - vhost -
- express.csrf - - csurf -
- express.directory - - serve-index -
- Uexpress.static - - Ave-estática -
+| Express 3 | Express 4 | +| ------------------------ | ------------------------------------------------------------------------------------------------------- | +| `express.bodyParser` | [body-parser](https://github.com/expressjs/body-parser) + [multer](https://github.com/expressjs/multer) | +| `express.compress` | [compression](https://github.com/expressjs/compression) | +| `express.cookieSession` | [cookie-session](https://github.com/expressjs/cookie-session) | +| `express.cookieParser` | [cookie-parser](https://github.com/expressjs/cookie-parser) | +| `express.logger` | [morgan](https://github.com/expressjs/morgan) | +| `express.session` | [express-session](https://github.com/expressjs/session) | +| `express.favicon` | [serve-favicon](https://github.com/expressjs/serve-favicon) | +| `express.responseTime` | [response-time](https://github.com/expressjs/response-time) | +| `express.errorHandler` | [errorhandler](https://github.com/expressjs/errorhandler) | +| `express.methodOverride` | [method-override](https://github.com/expressjs/method-override) | +| `express.timeout` | [connect-timeout](https://github.com/expressjs/timeout) | +| `express.vhost` | [vhost](https://github.com/expressjs/vhost) | +| `express.csrf` | [csurf](https://github.com/expressjs/csurf) | +| `express.directory` | [serve-index](https://github.com/expressjs/serve-index) | +| `express.static` | [serve-static](https://github.com/expressjs/serve-static) | Aqui está a [lista completa](https://github.com/senchalabs/connect#middleware) de Express 4 middleware. @@ -305,78 +195,21 @@ que é específico da rota. A tabela a seguir lista outras pequenas mas importantes mudanças no Express 4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ObjectDescrição
Node.jsExpress 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x.
`http.createServer()` - O módulo `http` não é mais necessário, a menos que você precise trabalhar diretamente com ele - (socket.io/SPDY/HTTPS). O aplicativo pode ser iniciado usando a função `app.listen()`. -
`app.configure()` - A função `app.configure()` foi removida. Use a função `process.env.NODE_ENV` ou - `app.get('env')` para detectar o ambiente e configurar o aplicativo de acordo. -
`espaços json` - A propriedade de aplicação `json spaces` está desativada por padrão no Express 4. -
`req.accepted()` - Use `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, e - `req.acceptsLanguages()`. -
`res.location()`Não resolve mais URLs relativas.
`req.params`Era um array; agora um objeto.
`res.locals`Era uma função; agora um objeto.
`res.headerSent`Alterado para `res.headers`.
`app.route`Agora disponível como `app.mountpath`.
`res.on('header')`removido.
`res.charset`removida.
`res.setHeader('Set-Cookie', val)` - A funcionalidade agora está limitada a definir o valor básico de cookie. Use `res.cookie()` - para adicionar funcionalidade. -
+| Object | Descrição: | +| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Node.js | Express 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x. | +| `http.createServer()` | The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). O aplicativo pode ser iniciado usando a função `app.listen()`. | +| `app.configure()` | A função `app.configure()` foi removida. Use a função `process.env.NODE_ENV` ou `app.get('env')` para detectar o ambiente e configurar o aplicativo de acordo. | +| `json spaces` | A propriedade de aplicação `json spaces` está desativada por padrão no Express 4. | +| `req.accepted()` | Use `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, e `req.acceptsLanguages()`. | +| `res.location()` | No longer resolves relative URLs. | +| `req.params` | Was an array; now an object. | +| `res.locals` | Was a function; now an object. | +| `res.headerSent` | Changed to `res.headersSent`. | +| `app.route` | Now available as `app.mountpath`. | +| `res.on('header')` | Removed. | +| `res.charset` | Removed. | +| `res.setHeader('Set-Cookie', val)` | A funcionalidade agora está limitada a definir o valor básico de cookie. Use `res.cookie()` for added functionality. | ## Exemplo de migração de aplicativos diff --git a/src/content/pages/pt-br/resources/middleware/body-parser.mdx b/src/content/pages/pt-br/resources/middleware/body-parser.mdx index 280018161e..8cb3469679 100644 --- a/src/content/pages/pt-br/resources/middleware/body-parser.mdx +++ b/src/content/pages/pt-br/resources/middleware/body-parser.mdx @@ -44,6 +44,10 @@ Este módulo fornece os seguintes analisadores: - [Text body parser](#bodyparsertextoptions) - [Analisador de forma codificado em URL](#bodyparserurlencodedoptions) +All parsers support automatic inflation of `gzip`, `br` (brotli), `deflate` +and `zstd` encodings. `zstd` is available in Node.js `^22.15.0` and +`>=23.8.0`. + Outros analisadores de corpo que você pode interessar: - [body](https://www.npmjs.com/package/body#readme) @@ -84,9 +88,8 @@ Os vários erros retornados por este módulo estão descritos na ### bodyParser.json([options]) Retorna um middleware que só analisa `json` e só olha para solicitações onde -o cabeçalho `Content-Type` corresponde à opção `type`. Este analisador aceita qualquer codificação -Unicode do corpo e suporta a inflação automática de codificações `gzip`, -`br` (brotli) e `deflate`. +o cabeçalho `Content-Type` corresponde à opção `type`. This parser accepts any +Unicode encoding of the body. Um novo objeto `body` contendo os dados analisados é preenchido no objeto `request` após o middleware (ou seja, `req.body`). @@ -146,9 +149,7 @@ da solicitação. A análise pode ser abortada lançando um erro. ### bodyParser.raw([options]) Retorna um middleware que analisa todos os corpos como um `Buffer` e só olha para -solicitações onde o cabeçalho `Content-Type` corresponde à opção `type`. Este analisador -suporta inflação automática de codificações `gzip`, `br` (brotli) e `deflate` -. +solicitações onde o cabeçalho `Content-Type` corresponde à opção `type`. Um novo objeto `body` contendo os dados analisados é preenchido no objeto `request` após o middleware (ou seja, `req.body`). Este será um objeto `Buffer` @@ -194,13 +195,11 @@ da solicitação. A análise pode ser abortada lançando um erro. ### bodyParser.text([options]) Retorna um middleware que analisa todos os corpos como uma seqüência de caracteres e só olha para -solicitações onde o cabeçalho `Content-Type` corresponde à opção `type`. Este analisador -suporta inflação automática de codificações `gzip`, `br` (brotli) e `deflate` -. +solicitações onde o cabeçalho `Content-Type` corresponde à opção `type`. -Uma nova string `body` contendo os dados analisados é preenchida no objeto `request` -após o middleware (ou seja, `req.body`). Será uma sequência de caracteres do corpo -. +A new `body` string containing the parsed data is populated on the `request` +object after the middleware (i.e. `req.body`). This will be a string of the +body. #### Opções @@ -209,8 +208,8 @@ the following keys: ##### padrãoCharset -Especifique o conjunto de caracteres padrão para o conteúdo de texto se o conjunto de caracteres não for -especificado no cabeçalho `Content-Type` da solicitação. Padrão para 'utf-8'. +Specify the default character set for the text content if the charset is not +specified in the `Content-Type` header of the request. Padrão para 'utf-8'. ##### inflar @@ -229,13 +228,13 @@ para `'100kb'`. ##### Tipo The `type` option is used to determine what media type the middleware will -parse. Esta opção pode ser uma string, um array de frases ou uma função. Se não for -uma função, A opção `type` é passada diretamente para a biblioteca -[type-is](https://www.npmjs.com/package/type-is#readme) e isto pode ser -um nome de extensão (como `txt`), um tipo MIME (como `text/plain`), ou um mime -com um curinga (como `*/*` ou `text/*`). Se uma função, a opção `type` -é chamada como `fn(req)` e a solicitação é analisada se ela retorna um valor verdadeiro de -. O padrão é 'texto/plain'. +parse. Esta opção pode ser uma string, um array de frases ou uma função. If not +a function, `type` option is passed directly to the +[type-is](https://www.npmjs.com/package/type-is#readme) library and this can +be an extension name (like `txt`), a mime type (like `text/plain`), or a mime +type with a wildcard (like `*/*` or `text/*`). If a function, the `type` +option is called as `fn(req)` and the request is parsed if it returns a +truthy value. Defaults to `text/plain`. ##### verificar @@ -245,29 +244,28 @@ da solicitação. A análise pode ser abortada lançando um erro. ### bodyParser.urlencoded([options]) -Retorna o middleware que só analisa os corpos `urlencoded` e só olha para -solicitações onde o cabeçalho `Content-Type` corresponde à opção `type`. Este analisador -aceita apenas codificações UTF-8 e ISO-8859-1 do corpo e suporta -inflação automática de codificações `gzip`, `br` (brotli) e `deflate`. +Returns middleware that only parses `urlencoded` bodies and only looks at +requests where the `Content-Type` header matches the `type` option. This +parser accepts only UTF-8 and ISO-8859-1 encodings of the body. Um novo objeto `body` contendo os dados analisados é preenchido no objeto `request` -após o middleware (ou seja, `req.body`). Este objeto conterá -pares de chave-valor, onde o valor pode ser uma string ou array (quando 'estendido' é -'false'), ou qualquer tipo (quando 'estendido' é 'true'). +após o middleware (ou seja, `req.body`). This object will contain +key-value pairs, where the value can be a string or array (when `extended` is +`false`), or any type (when `extended` is `true`). #### Opções -A função `urlencoded` recebe um objeto `options` opcional que pode conter -qualquer uma das seguintes chaves: +The `urlencoded` function takes an optional `options` object that may contain +any of the following keys: -##### estendido +##### extended The "extended" syntax allows for rich objects and arrays to be encoded into the -URL-encoded format, allowing for a JSON-like experience with URL-encoded. Para -mais informações, por favor veja as configurações rápidas -biblioteca. +URL-encoded format, allowing for a JSON-like experience with URL-encoded. For +more information, please see the qs +library. -O padrão é 'false'. +Defaults to `false`. ##### inflar @@ -283,23 +281,23 @@ para `'100kb'`. > É recomendado não configurar um limite muito alto e usar o valor padrão sempre que possível. Permitir que cargas maiores aumenta o uso de memória por causa dos recursos necessários para decodificação e transformações, e também pode levar a tempos de resposta mais longos à medida que mais dados são processados. Por "muito alto", queremos dizer valores acima do padrão, por exemplo, pagamentos de 5 MB ou mais já podem começar a introduzir esses riscos. Com os limites padrão, estas questões não ocorrem. -##### limiteParâmetro +##### parameterLimit -A opção `parameterLimit` controla o número máximo de parâmetros que -são permitidos nos dados codificados pela URL. Se um pedido contém mais parâmetros -do que esse valor, um 413 será devolvido ao cliente. O padrão é `1000`. +The `parameterLimit` option controls the maximum number of parameters that +are allowed in the URL-encoded data. If a request contains more parameters +than this value, a 413 will be returned to the client. Defaults to `1000`. ##### Tipo The `type` option is used to determine what media type the middleware will -parse. Esta opção pode ser uma string, um array de frases ou uma função. Se não for -uma função, A opção `type` é passada diretamente para a biblioteca -[type-is](https://www.npmjs.com/package/type-is#readme) e isto pode ser -um nome de extensão (como `urlencoded`), um tipo de mime (como -`application/x-www-form-urlencoded`), ou um tipo de mime com um curinga (como -`*/x-www-form-urlencoded`). Se uma função, a opção `tipo` for chamada como -`fn(req)` e a solicitação for analisada se ela retornar um valor verdadeiro. O padrão -é `application/x-www-form-urlencoded`. +parse. Esta opção pode ser uma string, um array de frases ou uma função. If not +a function, `type` option is passed directly to the +[type-is](https://www.npmjs.com/package/type-is#readme) library and this can +be an extension name (like `urlencoded`), a mime type (like +`application/x-www-form-urlencoded`), or a mime type with a wildcard (like +`*/x-www-form-urlencoded`). If a function, the `type` option is called as +`fn(req)` and the request is parsed if it returns a truthy value. Defaults +to `application/x-www-form-urlencoded`. ##### verificar @@ -309,131 +307,131 @@ da solicitação. A análise pode ser abortada lançando um erro. ##### padrãoCharset -O conjunto de caracteres padrão para analisar como, se não for especificado no tipo de conteúdo. Deve ser -`utf-8` ou `iso-8859-1`. Padrão para 'utf-8'. +The default charset to parse as, if not specified in content-type. Must be +either `utf-8` or `iso-8859-1`. Padrão para 'utf-8'. ##### charsetSentinel -Se deseja deixar o valor do parâmetro `utf8` ter precedência como seletor de conjunto de caracteres -. It requires the form to contain a parameter named `utf8` with a value -of `✓`. O padrão é 'false'. +Whether to let the value of the `utf8` parameter take precedence as the charset +selector. It requires the form to contain a parameter named `utf8` with a value +of `✓`. Defaults to `false`. -##### interpretaçõesNuméricas +##### interpretNumericEntities -Se deve decodificar entidades numéricas como `☺` ao analisar um formulário iso-8859-1 -. O padrão é 'false'. +Whether to decode numeric entities such as `☺` when parsing an iso-8859-1 +form. Defaults to `false`. -##### profundidade +##### depth -A opção `profunde` é usada para configurar a profundidade máxima da biblioteca `qs` quando `extended` é `true`. Isso permite que você limite a quantidade de chaves que são analisadas e podem ser úteis para evitar certos tipos de abusos. O padrão é `32`. Recomenda-se manter este valor o mais baixo possível. +The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible. -## Erros +## Errors -Os middlewares fornecidos por este módulo criam erros usando o módulo -[`http-errors`](https://www.npmjs.com/package/http-errors). Os erros -normalmente terão uma propriedade `status`/`statusCode` que contém o código de resposta -HTTP sugerido, uma propriedade `expose` para determinar se a propriedade `message` -deve ser exibida para o cliente, uma propriedade `type` para determinar o tipo de erro -sem corresponder à `message`, e uma propriedade `body` contendo -o corpo de leitura, se disponível. +The middlewares provided by this module create errors using the +[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors +will typically have a `status`/`statusCode` property that contains the suggested +HTTP response code, an `expose` property to determine if the `message` property +should be displayed to the client, a `type` property to determine the type of +error without matching against the `message`, and a `body` property containing +the read body, if available. -Os seguintes são os erros comuns criados, embora qualquer erro possa vir -por vários motivos. +The following are the common errors created, though any error can come through +for various reasons. -### codificação de conteúdo não suportada +### content encoding unsupported -Este erro ocorrerá quando a solicitação tiver um cabeçalho `Content-Encoding` que -continha uma codificação, mas a opção "inflação" foi definida como `false`. A propriedade -`status` está definida como `415`, a propriedade `type` está definida como -`'encoding. nsupported'`, e a propriedade `charset` será definida para -codificação que não é suportada. +This error will occur when the request had a `Content-Encoding` header that +contained an encoding but the "inflation" option was set to `false`. The +`status` property is set to `415`, the `type` property is set to +`'encoding.unsupported'`, and the `charset` property will be set to the +encoding that is unsupported. -### falha ao analisar entidade +### entity parse failed This error will occur when the request contained an entity that could not be -parsed by the middleware. A propriedade `status` está definida como `400`, a propriedade `type` -está definida como `'entity.parse. ailed'`, e a propriedade `body` está definida para -o valor da entidade que falhou no analisamento. +parsed by the middleware. The `status` property is set to `400`, the `type` +property is set to `'entity.parse.failed'`, and the `body` property is set to +the entity value that failed parsing. -### verificação da entidade falhou +### entity verify failed -Este erro ocorrerá quando a solicitação contiver uma entidade que não pôde ser -falha na verificação pela opção 'verificação' definida. A propriedade `status` está -definida como `403`, a propriedade `type` está definida como `'entity.verify. ailed'`, e a propriedade -`body` está definida para o valor da entidade que falhou na verificação. +This error will occur when the request contained an entity that could not be +verified by the defined `verify` option. The `status` property is +set to `403`, the `type` property is set to `'entity.verify.failed'`, and the +`body` property is set to the entity value that failed verification. -### solicitação cancelada +### request aborted -Este erro ocorrerá quando a solicitação é abortada pelo cliente antes de ler -o corpo concluiu. A propriedade `recebido` será definida como o número de -bytes recebidos antes da solicitação ser cancelada e a propriedade `expected` é -definida como o número de bytes esperados. A propriedade `status` está definida como `400` -e `type` está definida como `'request.aborted'`. +This error will occur when the request is aborted by the client before reading +the body has finished. The `received` property will be set to the number of +bytes received before the request was aborted and the `expected` property is +set to the number of expected bytes. The `status` property is set to `400` +and `type` property is set to `'request.aborted'`. -### solicitar entidade muito grande +### request entity too large -Este erro ocorrerá quando o tamanho do corpo da solicitação for maior que o "limite" -opção. A propriedade `limite` será definida para o limite de bytes e a propriedade `comprimento` -será definida para o comprimento do corpo da requisição. A propriedade `status` é -definida como `413` e a propriedade `type` está definida como `'entity.too.large'`. +This error will occur when the request body's size is larger than the "limit" +option. The `limit` property will be set to the byte limit and the `length` +property will be set to the request body's length. The `status` property is +set to `413` and the `type` property is set to `'entity.too.large'`. -### tamanho da solicitação não corresponde ao tamanho do conteúdo +### request size did not match content length This error will occur when the request's length did not match the length from -the `Content-Length` header. Isso normalmente ocorre quando a solicitação é malformada, -normalmente quando o cabeçalho `Content-Length` foi calculado com base nos caracteres -em vez de bytes. A propriedade `status` está definida como `400` e a propriedade `type` -está definida como `'request.size.invalid'`. +the `Content-Length` header. This typically occurs when the request is malformed, +typically when the `Content-Length` header was calculated based on characters +instead of bytes. The `status` property is set to `400` and the `type` property +is set to `'request.size.invalid'`. -### codificação de fluxo não deve ser definida +### stream encoding should not be set -Este erro ocorrerá quando algo chamado o método `req.setEncoding` anterior a -a este middleware. Este módulo opera somente diretamente em bytes e você não pode -chamar `req.setEncoding` ao usar este módulo. A propriedade `status` está definida como -`500` e a propriedade `type` está definida para `'stream.encoding.set'`. +This error will occur when something called the `req.setEncoding` method prior +to this middleware. This module operates directly on bytes only and you cannot +call `req.setEncoding` when using this module. The `status` property is set to +`500` and the `type` property is set to `'stream.encoding.set'`. -### transmissão não está legível +### stream is not readable -Este erro ocorrerá quando a solicitação não estiver mais legível quando este middleware -tentar lê-lo. Isso normalmente significa algo diferente de um middleware de -este módulo leu o corpo da solicitação e o middleware também foi configurado para -ler o mesmo pedido. A propriedade `status` é definida como `500` e `type` -é definida como `'stream.not.readable'`. +This error will occur when the request is no longer readable when this middleware +attempts to read it. This typically means something other than a middleware from +this module read the request body already and the middleware was also configured to +read the same request. The `status` property is set to `500` and the `type` +property is set to `'stream.not.readable'`. -### parâmetros demais +### too many parameters -Este erro ocorrerá quando o conteúdo da solicitação exceder o -`parameterLimit` configurado para o analisador `urlencoded`. A propriedade `status` é definida como -`413` e a propriedade `type` é definida como `'parameters.too.many'`. +This error will occur when the content of the request exceeds the configured +`parameterLimit` for the `urlencoded` parser. The `status` property is set to +`413` and the `type` property is set to `'parameters.too.many'`. -### charset "BOGUS" não suportado +### unsupported charset "BOGUS" -Este erro ocorrerá quando a solicitação teve um parâmetro de conjunto de caracteres no cabeçalho -`Content-Type`, mas o módulo `iconv-lite` não suporta OU o analisador -não suporta. O conjunto de caracteres está contido na mensagem e -como na propriedade `charset`. A propriedade `status` está definida como `415`, a propriedade -`type` está definida como `'charset. nsupported'`, e a propriedade `charset` -está definida para o conjunto de caracteres que não é suportado. +This error will occur when the request had a charset parameter in the +`Content-Type` header, but the `iconv-lite` module does not support it OR the +parser does not support it. The charset is contained in the message as well +as in the `charset` property. The `status` property is set to `415`, the +`type` property is set to `'charset.unsupported'`, and the `charset` property +is set to the charset that is unsupported. -### codificação de conteúdo "bogus" não suportada +### unsupported content encoding "bogus" -Este erro ocorrerá quando a solicitação tiver um cabeçalho `Content-Encoding` que -continha uma codificação não suportada. A codificação está contida na mensagem -bem como na propriedade `encoding`. A propriedade `status` está definida como `415`, -a propriedade `type` está definida como `'encoding. nsupported'`, e a propriedade `encoding` -é definida para a codificação que não é suportada. +This error will occur when the request had a `Content-Encoding` header that +contained an unsupported encoding. The encoding is contained in the message +as well as in the `encoding` property. The `status` property is set to `415`, +the `type` property is set to `'encoding.unsupported'`, and the `encoding` +property is set to the encoding that is unsupported. -### A entrada excedeu a profundidade +### The input exceeded the depth -Este erro ocorre ao usar `bodyParser.urlencoded` com a propriedade `extended` definida como `true` e a entrada excede a opção `depth` configurada. A propriedade `status` está definida para `400`. É recomendado rever a opção de profundidade e avaliar se ela requer um valor mais alto. Quando a opção 'profundeza' estiver definida como '32' (valor padrão), o erro não será lançado. +This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown. ## Exemplos -### Expresso/Conectar genérico de nível superior +### Express/Connect top-level generic -Este exemplo demonstra adicionar um analisador JSON genérico e codificado em URLs como um intermediário de nível superior -, que analisará os corpos de todas as solicitações de entrada. -Esta é a configuração mais simples. +This example demonstrates adding a generic JSON and URL-encoded parser as a +top-level middleware, which will parse the bodies of all incoming requests. +This is the simplest setup. ```js const express = require('express'); @@ -454,10 +452,10 @@ app.use(function (req, res) { }); ``` -### Expressar rota específica +### Express route-specific -Este exemplo demonstra adicionar analisadores corporais especificamente às rotas que -precisam delas. Em geral, esta é a maneira mais recomendada de usar o analisador corporal com +This example demonstrates adding body parsers specifically to the routes that +need them. In general, this is the most recommended way to use body-parser with Express. ```js @@ -485,10 +483,10 @@ app.post('/api/users', jsonParser, function (req, res) { }); ``` -### Alterar o tipo aceito para analisadores +### Change accepted type for parsers -Todos os analisadores aceitam uma opção `type` que permite mudar o `Content-Type` -que o middleware analisará. +All the parsers accept a `type` option which allows you to change the +`Content-Type` that the middleware will parse. ```js const express = require('express'); @@ -511,5 +509,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 -[medalha ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge -[visualizador ossf-scorecard]: 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/pt-br/resources/middleware/compression.mdx b/src/content/pages/pt-br/resources/middleware/compression.mdx index 5dc107d69f..53b1e522f2 100644 --- a/src/content/pages/pt-br/resources/middleware/compression.mdx +++ b/src/content/pages/pt-br/resources/middleware/compression.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -21,13 +21,13 @@ As seguintes codificações de compressão são suportadas: - gzip - br (brotli) -**Nota** Brotli só é suportado desde versões Node.js v11.7.0 e v10.16.0. +**Note** Brotli is available in all currently supported Node.js LTS versions (v18+). ## Instale Este é um módulo [Node.js](https://nodejs.org/en/) disponível através do [registro do npm](https://www.npmjs.com/). A instalação é feita usando o comando -[`npm install`](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): +[`npm install`](https://docs.npmjs.com/downloading-and-installing-packages-locally): @@ -304,7 +304,7 @@ O projeto Express.js congratula-se com todas as contribuições construtivas. Co do código para correções de bugs e aprimoramentos, para complementos e correções na documentação, testes adicionais, fazendo triagem de pull requests e problemas de entrada, e muito mais! -Veja o [Guia de Contribuição](https://github.com/expressjs/express/blob/master/Contributing.md) para mais detalhes técnicos sobre a contribuição. +See the [Contributing Guide](https://github.com/expressjs/.github/blob/HEAD/CONTRIBUTING.md) for more technical details on contributing. ## Tipo: @@ -312,6 +312,6 @@ Veja o [Guia de Contribuição](https://github.com/expressjs/express/blob/master [npm-url]: https://npmjs.org/package/compression [URL-download]: https://npmcharts.com/compare/compression?minimal=true -[medalha ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge -[visualizador ossf-scorecard]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression +[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 [url de financiamento]: https://opencollective.com/pt/expressa diff --git a/src/content/pages/pt-br/resources/middleware/morgan.mdx b/src/content/pages/pt-br/resources/middleware/morgan.mdx index d4416b29ee..bb9455b95a 100644 --- a/src/content/pages/pt-br/resources/middleware/morgan.mdx +++ b/src/content/pages/pt-br/resources/middleware/morgan.mdx @@ -8,14 +8,14 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; Requisição de logger middleware HTTP para node.js -> Nomeado após [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), uma série que você não deve assistir até a conclusão. +> Named after [Dexter](https://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. ## Instalação @@ -35,6 +35,16 @@ Este é um módulo [Node.js](https://nodejs.org/en/) disponível através do ## API +For ES Modules: + +{/* eslint-disable no-unused-vars */} + +```js +import morgan from 'morgan'; +``` + +For CommonJS: + {/* eslint-disable no-unused-vars */} ```js @@ -78,10 +88,12 @@ morgan(function (tokens, req, res) { tokens.method(req, res), tokens.url(req, res), tokens.status(req, res), - tokens.res(req, res, 'content-length'), '-', - tokens['response-time'](https://github.com/expressjs/morgan/blob/HEAD/req, res), 'ms' - ].join(' ') -}) + tokens.res(req, res, 'content-length'), + '-', + tokens['response-time'](req, res), + 'ms', + ].join(' '); +}); ``` #### Opções @@ -90,9 +102,9 @@ Morgan aceita essas propriedades no objeto de opções. ##### imediato -Escrever linha de log na solicitação em vez de resposta. Isso significa que um pedido será registrado -mesmo que o servidor falhe, _mas dados da resposta (como o código -de resposta, comprimento de conteúdo, etc.) não pode ser logado_. +Escrever linha de log na solicitação em vez de resposta. This means that requests will +be logged even if the server crashes, _but data from the response (like the +response code, content length, etc.) não pode ser logado_. ##### Pular @@ -114,6 +126,33 @@ morgan('combined', { Fluxo de saída para escrever linhas de log, padrão para `process.stdout`. +If the stream is in object mode (`stream.writableObjectMode` is `true`) and the +format function returns an object, the object is written to the stream as-is, +without a trailing newline. This allows passing structured log entries to +loggers that accept objects: + +{/* eslint-disable no-undef */} + +```js +morgan( + function (tokens, req, res) { + return { + method: tokens.method(req, res), + url: tokens.url(req, res), + status: Number(tokens.status(req, res)), + }; + }, + { + stream: { + writableObjectMode: true, + write: function (entry) { + // entry is the object returned by the format function + }, + }, + } +); +``` + #### Formatos predefinidos Existem vários formatos predefinidos fornecidos: @@ -151,6 +190,11 @@ não coloridos para códigos de informação. GET /dev 200 0.224 ms - 2 ``` +Coloring is disabled when the [`NO_COLOR`](https://no-color.org) environment +variable is set to any non-empty value, in which case the output above is +written without any escape sequences. The variable is read once, when `morgan` +is first required. + ##### curto Menor que o padrão, incluindo também o tempo de resposta. @@ -191,8 +235,8 @@ Chamando `morgan.token()` usando o mesmo nome que um token existente substituir do token. Espera-se que a função de token seja chamada com os argumentos `req` e `res`, representando -a solicitação HTTP e a resposta HTTP. Além disso, o token pode aceitar mais argumentos de -que ele escolheu personalizar o comportamento. +a solicitação HTTP e a resposta HTTP. Additionally, the token can accept further arguments of +its choosing to customize behavior. ##### :date[format] @@ -218,7 +262,7 @@ O ID do processo do Node.js lidando com a solicitação. ##### -O cabeçalho do Referrer da solicitação. Isto usará o cabeçalho Referer de ortografia incorreta se existir, caso contrário será Referente. +O cabeçalho do Referrer da solicitação. This will use the standard mis-spelled Referer header if it exists, otherwise Referrer. ##### :remote-addr @@ -264,7 +308,7 @@ incluir no número, por padrão até `3`, que fornece precisão de microsegundos ##### -A URL da solicitação. Isto usará `req.originalUrl` se existir, caso contrário `req.url`. +A URL da solicitação. This will use `req.originalUrl` if it exists, otherwise `req.url`. ##### :user-agent @@ -274,13 +318,13 @@ O conteúdo do cabeçalho User-Agent da solicitação. Compilar uma string de formato em uma função `format` para usar por `morgan`. Uma string de formato é uma string que representa uma única linha de log e pode utilizar a sintaxe do token. -Tokens são referências por `:token-name`. If tokens accept arguments, they can +Tokens are referenced by `:token-name`. If tokens accept arguments, they can be passed using `[]`, for example: `:token-name[pretty]` would pass the string `'pretty'` as an argument to the token `token-name`. -A função retornada de `morgan. ompile` recebe três argumentos `tokens`, `req`, e -`res`, onde `tokens` é objeto com todos os tokens definidos, `req` é a solicitação HTTP e -`res` é a resposta HTTP. A função retornará uma string que será a linha de log, +The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and +`res`, where `tokens` is an object with all defined tokens, `req` is the HTTP request and +`res` is the HTTP response. A função retornará uma string que será a linha de log, ou `undefined` / `null` para pular o log. Normally formats are defined using `morgan.format(name, format)`, but for certain @@ -290,7 +334,7 @@ advanced uses, this compile function is directly available. ### expressão/conexão -Aplicativo de exemplo que registrará todos os pedidos no formato combinado do Apache para STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var express = require('express'); @@ -307,7 +351,7 @@ app.get('/', function (req, res) { ### servidor http vanilla -Aplicativo de exemplo que registrará todos os pedidos no formato combinado do Apache para STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var finalhandler = require('finalhandler'); @@ -431,7 +475,7 @@ Exemplo de aplicativo que usará formatos de token personalizados. Isso adiciona ```js var express = require('express'); var morgan = require('morgan'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); morgan.token('id', function getId(req) { return req.id; diff --git a/src/content/pages/pt-br/resources/middleware/multer.mdx b/src/content/pages/pt-br/resources/middleware/multer.mdx index 0c56c25b75..f678c0d137 100644 --- a/src/content/pages/pt-br/resources/middleware/multer.mdx +++ b/src/content/pages/pt-br/resources/middleware/multer.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -18,23 +18,6 @@ sobre [busboy](https://github.com/mscdex/busboy) para uma eficiência máxima. **OBSERVAÇÃO**: Multer não irá processar nenhum formulário que não seja multiparte (`multipart/form-data`). -## Traduções - -Este README também está disponível em outros idiomas: - -| | | -| ------------------------------------------------------------------------------ | -------------- | -| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arábico | -| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | chinês | -| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | francês | -| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | coreano | -| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Português (BR) | -| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russo | -| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | espanhol | -| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek | -| 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) | Turco | - ## Instalação @@ -130,23 +113,26 @@ app.post('/stats', upload.single('uploaded_file'), function (req, res) { }); ``` +Complete client-side and server-side examples (browser `FormData` uploads of a +blob and of an image) are in the [`examples/`](https://github.com/expressjs/multer/blob/HEAD/examples/) folder. + ## API ### Informação do arquivo Cada arquivo contém as seguintes informações: -| Chave | Descrição: | Observação | -| -------------- | ----------------------------------------- | --------------- | -| `nomedocampo` | Nome do campo especificado no formulário | | -| `originalname` | Nome do arquivo no computador do usuário | | -| encoding\` | Tipo de codificação do arquivo | | -| `mimetype` | Tipo MIME do arquivo | | -| `size` | Tamanho do arquivo em bytes | | -| `destino` | A pasta na qual o arquivo foi salvo | `DiskStorage` | -| `nome_arquivo` | O nome do arquivo dentro do `destino` | `DiskStorage` | -| `caminho` | O caminho completo para o arquivo enviado | `DiskStorage` | -| `buffer` | Um `Buffer` de todo o arquivo | `MemoryStorage` | +| Chave | Descrição: | Observação | +| -------------- | ----------------------------------------------------------------------------------- | --------------- | +| `nomedocampo` | Nome do campo especificado no formulário | | +| `originalname` | Name of the file on the user's computer, or the full path when `preservePath: true` | | +| encoding\` | Tipo de codificação do arquivo | | +| `mimetype` | Tipo MIME do arquivo | | +| `size` | Tamanho do arquivo em bytes | | +| `destino` | A pasta na qual o arquivo foi salvo | `DiskStorage` | +| `nome_arquivo` | O nome do arquivo dentro do `destino` | `DiskStorage` | +| `caminho` | O caminho completo para o arquivo enviado | `DiskStorage` | +| `buffer` | Um `Buffer` de todo o arquivo | `MemoryStorage` | ### `multer(opts)` @@ -161,11 +147,15 @@ As seguintes são as opções que podem ser passadas para o Multer. | Chave | Descrição: | | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `defCharset` | Default character set to use for text field values that do not declare one. Default: `'utf8'` | +| `defParamCharset` | Conjunto de caracteres padrão para usar para valores dos parâmetros do cabeçalho das partes (por exemplo, nome do arquivo) que não são parâmetros estendidos (que contêm um conjunto de caracteres explícito). Padrão: `'latin1'` | | `dest` ou `armazenamento` | Onde armazenar os arquivos | | `FiltroArquivo` | Função para controlar quais arquivos são aceitos | +| `fileHwm` | `highWaterMark` of each file stream (`file.stream`). Default: busboy's default | +| `highWaterMark` | `highWaterMark` of the multipart parser stream. Default: busboy's default | | `limits` | Limites dos dados enviados | -| `preservePath` | Manter o caminho completo dos arquivos em vez de apenas o nome da base | -| `defParamCharset` | Conjunto de caracteres padrão para usar para valores dos parâmetros do cabeçalho das partes (por exemplo, nome do arquivo) que não são parâmetros estendidos (que contêm um conjunto de caracteres explícito). Padrão: `'latin1'` | +| `preservePath` | Keep the full client-supplied path in `file.originalname` instead of just the base name | +| `streamHandler` | Function that feeds the request body to busboy; defaults to `req.pipe(busboy)` | Em um aplicativo web comum, apenas `dest` pode ser necessário e configurado como mostrado em o exemplo a seguir. @@ -174,6 +164,14 @@ o exemplo a seguir. const upload = multer({ dest: 'uploads/' }); ``` +When `preservePath` is enabled, Multer passes the incoming filename through with +any path segments provided by the client. This is exposed as `file.originalname`; +it does not change the destination folder, create directories, or sanitize the +path for you. `file.originalname` is always client-supplied and should be treated +as untrusted; with `preservePath` it additionally contains the path segments the +client sent. Normalize or validate it before using it in a custom `filename` or +storage engine. + Se você quer mais controle sobre seus uploads, você vai querer usar a opção `storage` ao invés de `dest`. Mergulho com motores de armazenamento `DiskStorage` e `MemoryStorage`; Mais motores estão disponíveis a partir de terceiros. @@ -189,6 +187,9 @@ Aceitar uma matriz de arquivos, tudo com o nome `fieldname`. Erro opcional se mais do que os arquivos 'maxCount' forem enviados. A matriz de arquivos será armazenada em `req.files`. +Files skipped by `fileFilter` do not count towards `maxCount`. Use +`limits.files` to bound how many files are read from a request. + #### `.fields(fields)` Aceitar uma mistura de arquivos, especificados por 'campos'. Um objeto com matrizes de arquivos @@ -206,12 +207,12 @@ Exemplo: #### `.none()` -Aceitar apenas campos de texto. Se qualquer envio de arquivo for feito, será emitido um erro com o código -"LIMIT_UNEXPECTED_FILE". +Aceitar apenas campos de texto. If any file upload is made, error with code +`LIMIT_UNEXPECTED_FILE` will be issued. #### `.any()` -Aceita todos os arquivos que vêm por cima. Um array de arquivos será armazenado em +Accepts all files that come over the wire. Um array de arquivos será armazenado em `req.files`. **AVISO:** Certifique-se de que você sempre manipula os arquivos que um usuário envia. @@ -226,21 +227,26 @@ onde você está manipulando os arquivos carregados. O mecanismo de armazenamento de disco dá controle total sobre o armazenamento de arquivos. ```javascript +const crypto = require('crypto'); + const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/tmp/my-uploads'); }, filename: function (req, file, cb) { - const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); - cb(null, file.fieldname + '-' + uniqueSuffix); + crypto.randomBytes(16, function (err, raw) { + if (err) return cb(err); + cb(null, file.fieldname + '-' + raw.toString('hex')); + }); }, }); const upload = multer({ storage: storage }); ``` -Existem duas opções disponíveis, `destino` e `nome do arquivo`. Elas são ambas -funções que determinam onde o arquivo deve ser armazenado. +There are three options available: `destination`, `filename` and `flush`. All of +them except `flush` are functions that determine where the file should be +stored. `destination` is used to determine within which folder the uploaded files should be stored. Isto também pode ser dado como uma `string` (por exemplo, `'/tmp/uploads'`). Se nenhum @@ -268,6 +274,14 @@ Para entender a convenção de chamada usada no callback (precisa passar null como o primeiro parâmetro), consulte [Node. s Erro na manipulação](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors) +`flush` is an optional boolean. When set to `true`, the file data is flushed to +disk with an `fsync` call before the upload handler runs, which prevents data +loss if the process or the system crashes while the data is still sitting in +the operating system's page cache. It is disabled by default because forcing a +disk flush on every upload has a performance cost. Note that this syncs the +file contents only; if the new directory entry must survive a crash as well, +fsync the destination directory yourself. + #### `MemoryStorage` O mecanismo de armazenamento de memória armazena os arquivos em memória como objetos `Buffer`. Ela @@ -287,20 +301,36 @@ armazenamento de memória for usado. ### `limits` -Um objeto especificando os limites de tamanho das seguintes propriedades opcionais. Multi passa este objeto diretamente no busboy e os detalhes das propriedades podem ser encontrados na [página do busboy](https://github.com/mscdex/busboy#busboy-methods). +Um objeto especificando os limites de tamanho das seguintes propriedades opcionais. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#exports). + +`limits` can also be a function that receives the request and returns such an +object. It is called once per request, before parsing starts, so limits can +depend on e.g. the authenticated user: + +```javascript +const upload = multer({ + limits: function (req) { + return { fileSize: req.user.maxUploadSize }; + }, +}); +``` + +Limits apply to the whole request; there is no per-file limit. To restrict +individual files by type or name, use `fileFilter` or a custom storage engine. Os seguintes valores de números inteiros estão disponíveis: -| Chave | Descrição: | Padrão | -| ------------------- | --------------------------------------------------------------------------------------------------- | --------- | -| `fieldNameSize` | Tamanho máximo do nome do campo | 100 bytes | -| `tamanhoDoCampo` | Tamanho máximo do campo (em bytes) | 1MB | -| 'campos' | Número máximo de campos não-arquivo | Infinito | -| `tamanhoArquivo` | Para formas multipartes, o tamanho máximo do arquivo (em bytes) | Infinito | -| `arquivos` | Para formulários multipartes, o número máximo de campos de arquivo | Infinito | -| peças\` | Para formulários multipartes, o número máximo de peças (campos + arquivos) | Infinito | -| `headerPairs` | Para formas de múltiplas partes, o número máximo de pares chave de cabeçalho=>valores para analisar | 2000 | -| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinito | +| Chave | Descrição: | Padrão | +| ---------------------- | --------------------------------------------------------------------------------------------------- | -------- | +| `fieldNameSize` | Tamanho máximo do nome do campo | Infinito | +| `tamanhoDoCampo` | Tamanho máximo do campo (em bytes) | 1MB | +| 'campos' | Número máximo de campos não-arquivo | Infinito | +| `tamanhoArquivo` | Para formas multipartes, o tamanho máximo do arquivo (em bytes) | Infinito | +| `arquivos` | Para formulários multipartes, o número máximo de campos de arquivo | Infinito | +| peças\` | Para formulários multipartes, o número máximo de peças (campos + arquivos) | Infinito | +| `headerPairs` | Para formas de múltiplas partes, o número máximo de pares chave de cabeçalho=>valores para analisar | 2000 | +| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinito | +| `fieldArrayIndexLimit` | Max numeric array index accepted inside a field name (e.g. `a[3]` uses index 3) | Infinito | Especificar os limites pode ajudar a proteger seu site contra ataques de negação de serviço (DoS). @@ -325,6 +355,30 @@ function fileFilter(req, file, cb) { } ``` +### `streamHandler` + +By default Multer reads the request with `req.pipe(busboy)`. Some platforms +consume the request body before your handlers run, so there is nothing left to +pipe. Google Cloud Functions and Firebase Functions, for example, expose the +already-read body as `req.rawBody`. Provide a `streamHandler` to feed busboy +yourself in that case: + +```javascript +const upload = multer({ + storage: multer.memoryStorage(), + streamHandler: function (req, busboy) { + if (req.rawBody) { + busboy.end(req.rawBody); + } else { + req.pipe(busboy); + } + }, +}); +``` + +The function receives the request and the busboy instance and must write the +whole multipart body to busboy and end it. + ## Security Specifying the [limits](#limits) can help protect your site against denial of service (DoS) attacks. The following limits are recommended for most applications: @@ -333,6 +387,7 @@ Specifying the [limits](#limits) can help protect your site against denial of se - `files` -- set to the maximum number of files per request - `fields` -- set to the maximum number of text fields per request - `fieldNestingDepth` -- set to the minimum depth your field names require (e.g. `3` for `a[b][c]`) +- `fieldArrayIndexLimit` -- set to the largest array index your field names require (e.g. `100` for `a[99]`) ## Manipulação de erros @@ -342,6 +397,11 @@ exibir uma boa página de erro usando [o caminho expresso padrão](/guide/error- Se você quiser capturar erros especificamente do Multer, você pode chamar a função middleware de si mesmo. Além disso, se você quiser pegar apenas [os erros de Multer](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), você pode usar a classe `MulterError` que está anexada ao objeto `multer` em si (e. . `err instanceof multer.MulterError`). +Multer errors carry a `code` (e.g. `LIMIT_FILE_SIZE`) and, when the error concerns +a specific field, its name in `field`. Errors about a specific file +(`LIMIT_FILE_SIZE`, `LIMIT_UNEXPECTED_FILE`) also expose the client-supplied file +name in `filename`; treat it as untrusted input, like `file.originalname`. + ```javascript const multer = require('multer'); const upload = multer().single('avatar'); @@ -368,5 +428,5 @@ Para obter informações sobre como construir seu próprio motor de armazenament [MIT](https://github.com/expressjs/multer/blob/HEAD/LICENSE) [npm-url]: https://npmjs.org/pacote/multer -[medalha ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[visualizador ossf-scorecard]: 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/pt-br/resources/middleware/serve-favicon.mdx b/src/content/pages/pt-br/resources/middleware/serve-favicon.mdx index eff2623a61..d29ccdd293 100644 --- a/src/content/pages/pt-br/resources/middleware/serve-favicon.mdx +++ b/src/content/pages/pt-br/resources/middleware/serve-favicon.mdx @@ -139,5 +139,5 @@ server.listen(3000); [URL-download]: https://npmjs.org/package/serve-favicon [npm-url]: https://npmjs.org/package/serve-favicon -[medalha ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/serve-favicon/badge -[visualizador ossf-scorecard]: 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/pt-br/resources/middleware/serve-index.mdx b/src/content/pages/pt-br/resources/middleware/serve-index.mdx index d0dbbaae5f..9ba044ca30 100644 --- a/src/content/pages/pt-br/resources/middleware/serve-index.mdx +++ b/src/content/pages/pt-br/resources/middleware/serve-index.mdx @@ -52,7 +52,7 @@ O índice Serve aceita essas propriedades no objeto de opções. ##### filtro -Aplicar esta função de filtro aos arquivos. O padrão é 'false'. A função `filter` +Aplicar esta função de filtro aos arquivos. Defaults to `false`. A função `filter` é chamada para cada arquivo, com a assinatura `filter(filename, index, arquivos, dir)` onde `filename` é o nome do arquivo, `index` é o índice do array, `files` é a matriz de arquivos e `dir` é o caminho absoluto que o arquivo está localizado (e assim, @@ -60,11 +60,11 @@ o diretório para o qual a listagem é destinada). ##### hidden -Exibir arquivos ocultos (pontos). O padrão é 'false'. +Exibir arquivos ocultos (pontos). Defaults to `false`. ##### ícones -Exibir ícones. O padrão é 'false'. +Exibir ícones. Defaults to `false`. ##### stylesheet @@ -149,8 +149,8 @@ app.listen(3000); ## Tipo: -[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). Os ícones [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) -são criados por/direitos autorais de [FAMFAMFAM](https://web.archive.org/web/20251120154741/http://www.famfamfam.com/). +[MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). The [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) icons +are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20230109095739/http://www.famfamfam.com/). [appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index [URL-download]: https://npmjs.org/package/serve-index diff --git a/src/content/pages/pt-br/resources/middleware/session.mdx b/src/content/pages/pt-br/resources/middleware/session.mdx index b7c1c4870d..99232f13f9 100644 --- a/src/content/pages/pt-br/resources/middleware/session.mdx +++ b/src/content/pages/pt-br/resources/middleware/session.mdx @@ -127,8 +127,8 @@ definido no objeto é o que é usado. ##### cookie.partitioned -Especifica o valor `booleano` para o atributo [`Partitioned` `Set-Cookie`](https://github.com/expressjs/session/blob/HEAD/rfc-cutler-httpbis-partitioned-cookies) -. Quando verdadeiro, o atributo `Particionado` é definido, caso contrário não está. +Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`][rfc-cutler-httpbis-partitioned-cookies] +attribute. Quando verdadeiro, o atributo `Particionado` é definido, caso contrário não está. Por padrão, o atributo 'Particionado' não está definido. **Nota** Esse é um atributo que ainda não foi totalmente padronizado, e @@ -142,6 +142,12 @@ Mais informações sobre pode ser encontrada na [proposta](https://github.com/pr Especifica o valor para o `Path` `Set-Cookie`. Por padrão, isso é definido como `/'`, que é o caminho de raiz do domínio. +Since 1.19.1, path matching follows [RFC 6265 section 5.1.4][rfc-6265-5.1.4]. This means +the session middleware will only activate when the request path is an exact match or falls +under a segment boundary of the cookie path. For example, a cookie path of `/admin` will +match `/admin` and `/admin/users` but will **not** match `/administrator`. Prior versions +used a simple prefix check that did not enforce segment boundaries. + ##### cookie.prioridade Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1]. @@ -1002,6 +1008,7 @@ No Windows, use o comando correspondente. [MIT](https://github.com/expressjs/session/blob/HEAD/LICENSE) +[rfc-6265-5.1.4]: https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 [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-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/ [rfc-west-cookie-prioridade-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1 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..8ca285b569 --- /dev/null +++ b/src/content/pages/zh-cn/advanced/best-practice-performance.mdx @@ -0,0 +1,332 @@ +--- +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 05fb6e9d2b..bdfe83a376 100644 --- a/src/content/pages/zh-cn/advanced/best-practice-security.mdx +++ b/src/content/pages/zh-cn/advanced/best-practice-security.mdx @@ -6,9 +6,9 @@ description: 了解Express应用部署至生产环境需遵循的关键安全最 import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -术语\*\*「生产环境」**指软件生命周期中应用或API面向终端用户、调用方正式对外开放的阶段。 与之相对,**「开发环境」**阶段中,开发者仍在编写与测试代码,应用暂不对外开放访问。 对应的系统环境分别称作**生产环境**与**开发环境\*\*。 +术语\*\*「生产环境」**指软件生命周期中应用或API面向终端用户、调用方正式对外开放的阶段。与之相对,**「开发环境」**阶段中,开发者仍在编写与测试代码,应用暂不对外开放访问。对应的系统环境分别称作**生产环境**与**开发环境\*\*。 -开发环境与生产环境通常配置不同,需求差异悬殊。 在开发环境中可行的配置,放到生产环境未必适用。 例如:开发环境下可开启详细错误日志用于调试,但相同配置在生产环境中会带来安全隐患。 开发阶段无需考量扩展性、可靠性与性能,而在生产环境中这些指标至关重要。 +开发环境与生产环境通常配置不同,需求差异悬殊。在开发环境中可行的配置,放到生产环境未必适用。例如:开发环境下可开启详细错误日志用于调试,但相同配置在生产环境中会带来安全隐患。开发阶段无需考量扩展性、可靠性与性能,而在生产环境中这些指标至关重要。 @@ -19,13 +19,13 @@ Policies and Procedures. ## 请勿使用已弃用或存在漏洞的 Express 版本 -Express 2.x 与 3.x 版本已不再维护。 这些版本中的安全与性能问题将不再进行修复。 不要使用它们! If you haven't moved to version 4, follow the [migration guide](/guide/migrating-4) or consider [Commercial Support Options](/support#commercial-support-options). +Express 2.x 与 3.x 版本已不再维护。这些版本中的安全与性能问题将不再进行修复。不要使用它们! If you haven't moved to version 4, follow the [migration guide](/guide/migrating-4) or consider [Commercial Support Options](/support#commercial-support-options). Also ensure you are not using any of the vulnerable Express versions listed on the [Security updates page](/advanced/security-updates). 如若正在使用,请升级至任一稳定版本,优先选择最新版。 ## 使用 TLS -如果您的应用处理或传输敏感数据,请使用 [传输图层安全](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) 来保护连接和数据。 该技术会在客户端向服务器发送数据前对数据进行加密,从而防范部分常见且易实施的攻击。 尽管 AJAX 和 POST 请求在浏览器中不会直观展现、看似处于 “隐藏” 状态,但它们的网络流量容易遭到[抓包分析](https://en.wikipedia.org/wiki/Packet_analyzer)与[中间人攻击](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). +如果您的应用处理或传输敏感数据,请使用 [传输图层安全](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) 来保护连接和数据。该技术会在客户端向服务器发送数据前对数据进行加密,从而防范部分常见且易实施的攻击。尽管 AJAX 和 POST 请求在浏览器中不会直观展现、看似处于 “隐藏” 状态,但它们的网络流量容易遭到[抓包分析](https://en.wikipedia.org/wiki/Packet_analyzer)与[中间人攻击](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). 你或许熟悉安全套接字层(SSL)加密。 In general, we recommend Nginx to handle TLS. 换言之,若此前使用SSL,建议升级至TLS。 In other words, if you were using SSL before, consider upgrading to TLS. For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (TLSRef)](https://docs.tlsref.org/server-side-tls.html#recommended-configurations). @@ -33,8 +33,7 @@ Also ensure you are not using any of the vulnerable Express versions listed on t ## 切勿信任用户输入 -对 Web 应用而言,最关键的安全要求之一是对用户输入进行合理的验证与处理。 这类风险形式多样,本文不逐一列举。 -最终,你需要全权负责验证并正确处理应用接收的各类用户输入。 +对 Web 应用而言,最关键的安全要求之一是对用户输入进行合理的验证与处理。这类风险形式多样,本文不逐一列举。最终,你需要全权负责验证并正确处理应用接收的各类用户输入。 ### 防止开放重定向 @@ -47,7 +46,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) { @@ -74,10 +73,10 @@ Helmet 是用于设置安全相关 HTTP 响应头的中间件函数。 Helmet - `X-Download-Options`:强制文件以下载形式保存(仅适用于 IE 浏览器) - `X-Frameworks`: 减少 [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) 攻击的遗留标题 - `X-Permitted-Cross-Domain-Policies`:控制Adobe系列产品(如Acrobat)的跨域行为 -- `X-Powered-By`:有关Web服务器的信息。 因易被用于简易攻击而移除 +- `X-Powered-By`:有关Web服务器的信息。因易被用于简易攻击而移除 - `X-XSS-Protection`:用于缓解[XSS攻击](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting)的旧式请求头,但会带来安全隐患,因此Helmet将其禁用 -每个请求头均可配置或禁用。 如需了解更多详情,请访问[其官方文档网站][helmet]。 +每个请求头均可配置或禁用。如需了解更多详情,请访问[其官方文档网站][helmet]。 像安装其他模块一样安装 Helmet: @@ -106,9 +105,8 @@ app.use(helmet()); ## 减少指纹识别 -它有助于提供额外的安全层,降低攻击者识别服务器所使用软件的能力,这种行为被称为“指纹识别”。 尽管其本身并非安全漏洞, -但降低应用程序的指纹识别能力可提升其整体安全状况。 -服务器软件可通过其响应特定请求的特征进行指纹识别,例如通过HTTP响应头中的特征。 +它有助于提供额外的安全层,降低攻击者识别服务器所使用软件的能力,这种行为被称为“指纹识别”。尽管其本身并非安全漏洞, +但降低应用程序的指纹识别能力可提升其整体安全状况。服务器软件可通过其响应特定请求的特征进行指纹识别,例如通过HTTP响应头中的特征。 默认情况下,Express 会发送 `X-Powered-By` 响应头,你可以使用 `app.disable()` 方法将其禁用: @@ -118,7 +116,7 @@ app.disable('x-powered-by'); -禁用 `X-Powered-By` 响应头并不能阻止老练的攻击者识别出应用正在运行 Express。 这或许能防范随意的漏洞利用,但仍有其他方法可以识别应用正在运行 Express。 +禁用 `X-Powered-By` 响应头并不能阻止老练的攻击者识别出应用正在运行 Express。这或许能防范随意的漏洞利用,但仍有其他方法可以识别应用正在运行 Express。 @@ -151,13 +149,13 @@ app.use((err, req, res, next) => { - [express-session](https://www.npmjs.com/package/express-session):替代了 Express 3.x 内置的 `express.session` 中间件。 - [cookie-session](https://www.npmjs.com/package/cookie-session):替代了 Express 3.x 内置的 `express.cookieSession` 中间件。 -这两个模块的主要区别在于它们存储 Cookie 会话数据的方式。 [express-session](https://www.npmjs.com/package/express-session) 中间件将会话数据存储在服务器端;它仅将会话ID保存到Cookie本身,不存储会话数据。 默认情况下,它使用内存存储,并非为生产环境设计。 In production, you'll need to set up a scalable session-store; see the list of [compatible session stores](https://github.com/expressjs/session#compatible-session-stores). +这两个模块的主要区别在于它们存储 Cookie 会话数据的方式。 [express-session](https://www.npmjs.com/package/express-session) 中间件将会话数据存储在服务器端;它仅将会话ID保存到Cookie本身,不存储会话数据。默认情况下,它使用内存存储,并非为生产环境设计。 In production, you'll need to set up a scalable session-store; see the list of [compatible session stores](https://github.com/expressjs/session#compatible-session-stores). -相比之下,[cookie-session](https://www.npmjs.com/package/cookie-session) 中间件实现基于Cookie的存储:它将整个会话序列化后存储到Cookie中,而非仅存储会话密钥。 仅当会话数据相对较小且易于编码为基本类型值(而非对象)时,才使用它。 尽管浏览器应支持每个Cookie至少4096字节,但为确保不超出限制,每个域的Cookie大小请勿超过4093字节。 此外,请注意**Cookie数据对客户端是可见的**,因此如果有任何需要保证数据安全或隐藏的需求,那么 `express-session` 会是更合适的选择。 +相比之下,[cookie-session](https://www.npmjs.com/package/cookie-session) 中间件实现基于Cookie的存储:它将整个会话序列化后存储到Cookie中,而非仅存储会话密钥。仅当会话数据相对较小且易于编码为基本类型值(而非对象)时,才使用它。尽管浏览器应支持每个Cookie至少4096字节,但为确保不超出限制,每个域的Cookie大小请勿超过4093字节。此外,请注意**Cookie数据对客户端是可见的**,因此如果有任何需要保证数据安全或隐藏的需求,那么 `express-session` 会是更合适的选择。 ### 不要使用默认的会话Cookie名称 -使用默认会话Cookie名称会使你的应用易遭受攻击。 由此带来的安全隐患与`X-Powered-By`类似:潜在攻击者可借此识别服务器指纹,并针对性发起攻击。 +使用默认会话Cookie名称会使你的应用易遭受攻击。由此带来的安全隐患与`X-Powered-By`类似:潜在攻击者可借此识别服务器指纹,并针对性发起攻击。 若要避免此问题,请使用通用的Cookie名称;例如使用 [express-session](https://www.npmjs.com/package/express-session) 中间件: @@ -190,8 +188,8 @@ app.use( - `secure` - 确保浏览器只通过 HTTPS 发送 cookie 。 - `httpOnly` - 确保 Cookie 仅通过 HTTP(S) 发送,不会被客户端 JavaScript 访问,有助于防范跨站脚本攻击。 -- `domain` - 表示 Cookie 的所属域名;用于将其与请求 URL 所在的服务器域名进行比对。 若匹配,则下一步检查路径属性。 -- `path` - 表示 Cookie 的路径;用于将其与请求路径进行比对。 若域名与路径均匹配,则在请求中发送该 Cookie。 +- `domain` - 表示 Cookie 的所属域名;用于将其与请求 URL 所在的服务器域名进行比对。若匹配,则下一步检查路径属性。 +- `path` - 表示 Cookie 的路径;用于将其与请求路径进行比对。若域名与路径均匹配,则在请求中发送该 Cookie。 - `expires` - use to set expiration date for persistent cookies. 以下是使用 [cookie-session](https://www.npmjs.com/package/cookie-session) 中间件的示例: @@ -246,15 +244,15 @@ app.use( 一种简单且有效的技巧是使用两个指标来阻止授权尝试: 1. 同一用户名和IP地址连续失败的尝试次数。 -2. 某一IP地址在较长时间段内的失败尝试次数。 例如,如果一个IP地址在一天内失败尝试100次,则阻止该IP地址。 +2. 某一IP地址在较长时间段内的失败尝试次数。例如,如果一个IP地址在一天内失败尝试100次,则阻止该IP地址。 -[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) 包提供了可简便快捷实现该技巧的工具。 你可以在文档中找到[暴力破解防护示例](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection) +[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) 包提供了可简便快捷实现该技巧的工具。你可以在文档中找到[暴力破解防护示例](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection) ## 确保你的依赖项安全 -使用 npm 管理应用依赖项功能强大且便捷。 但你使用的软件包可能包含严重的安全漏洞,这些漏洞同样会影响你的应用。 应用的安全性仅取决于依赖项中**最薄弱的环节**。 +使用 npm 管理应用依赖项功能强大且便捷。但你使用的软件包可能包含严重的安全漏洞,这些漏洞同样会影响你的应用。应用的安全性仅取决于依赖项中**最薄弱的环节**。 -从 npm@6 版本开始,npm 会自动审查每一次安装请求。 此外,你可以使用 `npm audit` 分析你的依赖树。 +从 npm@6 版本开始,npm 会自动审查每一次安装请求。此外,你可以使用 `npm audit` 分析你的依赖树。 ```bash $ npm audit @@ -283,12 +281,12 @@ Keep an eye out for [GitHub Advisory Database](https://github.com/advisories?que ## 其他注意事项 -以下是源自优质文档 [Node.js 安全检查清单](https://blog.risingstack.com/node-js-security-checklist/) 的补充建议。 关于这些建议的所有详细信息,请参阅该博客帖子: +以下是源自优质文档 [Node.js 安全检查清单](https://blog.risingstack.com/node-js-security-checklist/) 的补充建议。关于这些建议的所有详细信息,请参阅该博客帖子: - 始终过滤并净化用户输入,防范跨站脚本(XSS)与命令注入攻击。 - 使用参数化查询或预处理语句防范 SQL 注入攻击。 - Use the open-source [sqlmap](http://sqlmap.org/) tool to detect SQL injection vulnerabilities in your app. - 使用 [nmap](https://nmap.org/) 和 [sslyze](https://github.com/nabla-c0d3/sslyze) 工具测试 SSL 加密套件、密钥、重协商配置以及证书有效性。 -- Use [safe-regex](https://www.npmjs.com/package/safe-regex) to ensure your regular expressions are not susceptible to [regular expression denial of service](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) attacks. +- Use [safe-regex](https://www.npmjs.com/package/safe-regex) to ensure your regular expressions are not susceptible to [regular expression denial of service](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) attacks. [helmet]: https://helmetjs.github.io/ 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..3201074277 --- /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/advanced/security-updates.mdx b/src/content/pages/zh-cn/advanced/security-updates.mdx index 9b480e5edf..747ac41196 100644 --- a/src/content/pages/zh-cn/advanced/security-updates.mdx +++ b/src/content/pages/zh-cn/advanced/security-updates.mdx @@ -37,11 +37,11 @@ Policies and Procedures. - 4.19.0, 4.19.1 - Fixed open redirect vulnerability in `res.location` and `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-rv95-896h-c2vc), [CVE-2024-29041](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-29041)). - 4.17.3 - - 依赖`qs`已更新以修复一处[安全漏洞](https://github.com/advisories/GHSA-hrpp-h998-j3pp)。 若使用了下述 API:`req.query`、`req.body`、`req.param`,该问题可能对你的应用造成影响。 + - 依赖`qs`已更新以修复一处[安全漏洞](https://github.com/advisories/GHSA-hrpp-h998-j3pp)。若使用了下述 API:`req.query`、`req.body`、`req.param`,该问题可能对你的应用造成影响。 - 4.16.0 - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). 如果使用了下列API,这可能会影响您的应用程序:`req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`。 - The dependency `mime` has been updated to address a [vulnerability](https://npmjs.com/advisories/535), but this issue does not impact Express. - - 依赖`send`已完成更新,用于防范[Node.js 8.5.0相关漏洞](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/)。 该问题仅会在 Node.js 8.5.0 特定版本中运行 Express 时产生影响。 + - 依赖`send`已完成更新,用于防范[Node.js 8.5.0相关漏洞](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/)。该问题仅会在 Node.js 8.5.0 特定版本中运行 Express 时产生影响。 - 4.15.5 - The dependency `debug` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. - The dependency `fresh` has been updated to address a [vulnerability](https://npmjs.com/advisories/526). 若你的应用使用了以下 API,则会受到影响:`express.static`、`req.fresh`、`res.json`、`res.jsonp`、`res.send`、`res.sendfile`、`res.sendFile`、`res.sendStatus`。 @@ -56,7 +56,7 @@ Policies and Procedures. - 4.8.8 - Fixed directory traversal vulnerabilities in `express.static` ([advisory](http://npmjs.com/advisories/32) , [CVE-2014-6394](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6394)). - 4.8.4 - - Node.js 0.10 在特定情况下可能会发生文件描述符(`fd`)泄漏,从而影响 `express.static` 和 `res.sendfile`。 恶意请求可能导致文件描述符(`fd`)泄漏,最终引发`EMFILE`错误并造成服务器无响应。 + - Node.js 0.10 在特定情况下可能会发生文件描述符(`fd`)泄漏,从而影响 `express.static` 和 `res.sendfile`。恶意请求可能导致文件描述符(`fd`)泄漏,最终引发`EMFILE`错误并造成服务器无响应。 - 4.8.0 - 查询字符串中包含极高索引的稀疏数组,可能导致进程内存耗尽并使服务器崩溃。 - 深度嵌套的查询字符串对象会导致进程阻塞,使服务器暂时无法响应。 @@ -66,7 +66,7 @@ Policies and Procedures. **Express 3.x 已终止生命周期,不再提供维护支持** -3.x 版本自2015年8月1日最后一次更新后,已知及潜在的安全、性能漏洞均不再修复。 强烈建议使用最新版本的 Express。 +3.x 版本自2015年8月1日最后一次更新后,已知及潜在的安全、性能漏洞均不再修复。强烈建议使用最新版本的 Express。 If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/support#commercial-support-options). @@ -79,7 +79,7 @@ If you are unable to upgrade past 3.x, please consider [Commercial Support Optio - 3.16.10 - 在 `expres.static` 中固定的目录遍历脆弱性。 - 3.16.6 - - Node.js 0.10 在特定情况下可能会发生文件描述符(`fd`)泄漏,从而影响 `express.static` 和 `res.sendfile`。 恶意请求可能导致文件描述符(`fd`)泄漏,最终引发`EMFILE`错误并造成服务器无响应。 + - Node.js 0.10 在特定情况下可能会发生文件描述符(`fd`)泄漏,从而影响 `express.static` 和 `res.sendfile`。恶意请求可能导致文件描述符(`fd`)泄漏,最终引发`EMFILE`错误并造成服务器无响应。 - 3.16.0 - 查询字符串中包含极高索引的稀疏数组,会导致进程内存耗尽并使服务器崩溃。 - 深度嵌套的查询字符串对象会导致进程阻塞,使服务器暂时无法响应。 diff --git a/src/content/pages/zh-cn/guide/database-integration.mdx b/src/content/pages/zh-cn/guide/database-integration.mdx index 16ca618551..d5822072a4 100644 --- a/src/content/pages/zh-cn/guide/database-integration.mdx +++ b/src/content/pages/zh-cn/guide/database-integration.mdx @@ -6,7 +6,7 @@ description: 了解如何将各种数据库与 Express.js 应用程序集成, import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -为 Express 应用添加连接数据库的功能,只需在应用中加载对应数据库的合适 Node.js 驱动程序即可。 本文简要说明如何在 Express 应用中添加并使用一些最流行的数据库系统 Node.js 模块: +为 Express 应用添加连接数据库的功能,只需在应用中加载对应数据库的合适 Node.js 驱动程序即可。本文简要说明如何在 Express 应用中添加并使用一些最流行的数据库系统 Node.js 模块: - [Cassandra](#cassandra) - [Couchbase](#couchbase) @@ -24,7 +24,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa -这些数据库驱动只是众多可选驱动中的一部分。 如需其他方案,可前往[npm](https://www.npmjs.com/)官网检索。 +这些数据库驱动只是众多可选驱动中的一部分。如需其他方案,可前往[npm](https://www.npmjs.com/)官网检索。 diff --git a/src/content/pages/zh-cn/guide/migrating-4.mdx b/src/content/pages/zh-cn/guide/migrating-4.mdx index 2a68db6179..9b3549b9ba 100644 --- a/src/content/pages/zh-cn/guide/migrating-4.mdx +++ b/src/content/pages/zh-cn/guide/migrating-4.mdx @@ -6,7 +6,7 @@ description: 一份将 Express.js 应用从 3 版迁移至 4 版的指南,涵 import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -Express 4 相对于 Express 3 是一个破坏性变更版本。 这意味着如果在依赖项中更新 Express 版本,现有的 Express 3 应用将**无法**正常运行。 +Express 4 相对于 Express 3 是一个破坏性变更版本。这意味着如果在依赖项中更新 Express 版本,现有的 Express 3 应用将**无法**正常运行。 本文包括: @@ -29,9 +29,9 @@ Express 4 中有几项重大变更: ### Express 核心和中间件系统的变更 -Express 4 不再依赖 Connect,并从核心中移除了所有内置中间件,`express.static` 函数除外。 这意味着 Express 现在是一个独立的路由与中间件 Web 框架,其版本和发布不再受中间件更新的影响。 +Express 4 不再依赖 Connect,并从核心中移除了所有内置中间件,`express.static` 函数除外。这意味着 Express 现在是一个独立的路由与中间件 Web 框架,其版本和发布不再受中间件更新的影响。 -由于不再包含内置中间件,你必须显式添加应用运行所需的全部中间件。 只需按照以下步骤操作: +由于不再包含内置中间件,你必须显式添加应用运行所需的全部中间件。只需按照以下步骤操作: 1. Install the module: `npm install --save \` 2. 在你的应用中,引入该模块:`require('module-name')` @@ -39,142 +39,31 @@ Express 4 不再依赖 Connect,并从核心中移除了所有内置中间件 下表列出了 Express 3 中间件及其在 Express 4 中的对应模块。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Express 3Express 4
- express.bodyParser - - body-parser + - multer -
- express.compress - - compression -
- express.cookieSession - - cookie-session -
- express.cookieParser - - cookie-parser -
- express.logger - - morgan -
- express.session - - express-session -
- express.favicon - - serve-favicon -
- express.responseTime - - response-time -
- express.errorHandler - - errorhandler -
- express.methodOverride - - method-override -
- express.timeout - - connect-timeout -
- express.vhost - - vhost -
- express.csrf - - csurf -
- express.directory - - serve-index -
- express.static - - serve-static -
+| Express 3 | Express 4 | +| ------------------------ | ------------------------------------------------------------------------------------------------------- | +| `express.bodyParser` | [body-parser](https://github.com/expressjs/body-parser) + [multer](https://github.com/expressjs/multer) | +| `express.compress` | [compression](https://github.com/expressjs/compression) | +| `express.cookieSession` | [cookie-session](https://github.com/expressjs/cookie-session) | +| `express.cookieParser` | [cookie-parser](https://github.com/expressjs/cookie-parser) | +| `express.logger` | [morgan](https://github.com/expressjs/morgan) | +| `express.session` | [express-session](https://github.com/expressjs/session) | +| `express.favicon` | [serve-favicon](https://github.com/expressjs/serve-favicon) | +| `express.responseTime` | [response-time](https://github.com/expressjs/response-time) | +| `express.errorHandler` | [errorhandler](https://github.com/expressjs/errorhandler) | +| `express.methodOverride` | [method-override](https://github.com/expressjs/method-override) | +| `express.timeout` | [connect-timeout](https://github.com/expressjs/timeout) | +| `express.vhost` | [vhost](https://github.com/expressjs/vhost) | +| `express.csrf` | [csurf](https://github.com/expressjs/csurf) | +| `express.directory` | [serve-index](https://github.com/expressjs/serve-index) | +| `express.static` | [serve-static](https://github.com/expressjs/serve-static) | 此处为 Express 4 中间件的[完整清单](https://github.com/senchalabs/connect#middleware)。 -大多数情况下,你只需将旧版3中间件替换为对应的Express 4版本即可。 详情请参阅 GitHub 上的模块文档。 +大多数情况下,你只需将旧版3中间件替换为对应的Express 4版本即可。详情请参阅 GitHub 上的模块文档。 #### `app.use` 接受参数 -在版本4中,你可以使用可变参数来定义加载中间件函数的路径,然后从路由处理程序中读取该参数的值。 -举个例子: +在版本4中,你可以使用可变参数来定义加载中间件函数的路径,然后从路由处理程序中读取该参数的值。举个例子: ```js app.use('/book/:id', (req, res, next) => { @@ -194,7 +83,7 @@ app.use('/book/:id', (req, res, next) => { #### `app.route()` 方法 -新增的 `app.route()` 方法支持你为路由路径创建可链式调用的路由处理程序。 由于路径在单一位置指定,因此创建模块化路由十分实用,同时还能减少冗余代码和拼写错误。 For more +新增的 `app.route()` 方法支持你为路由路径创建可链式调用的路由处理程序。由于路径在单一位置指定,因此创建模块化路由十分实用,同时还能减少冗余代码和拼写错误。 For more information about routes, see [`Router()` documentation](/4x/api#router). 以下是使用 `app.route()` 函数定义的链式路由处理程序示例。 @@ -288,80 +177,25 @@ app.use('/birds', birds); 下表列出了 Express 4 中其他细微但重要的变更: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ObjectDescription
Node.jsExpress 4 requires Node.js 0.10.x 或更高版本,并且已经放弃了对 Node.js 0.8.x的支持。
`http.createServer()` - 不再需要`http`模块,除非你需要直接使用 (socket.io/SPDY/HTTPS). 可通过 `app.listen()` - 函数启动应用。 -
`app.configure()` - `app.configure()` 函数已被删除。 使用 `process.env.NODE_ENV` 或 `app.get('env)` - 函数检测环境并相应配置应用程序。 -
`json spaces`Express 4默认禁用了 "json spaces" 应用程序属性。
`req.accepted()` - 使用`req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, 和 - `req.acceptsLanguages()`. -
`res.location()`不再解析相对 URL。
`req.params`原为数组;现为对象。
`res.locals`原为函数;现为对象。
"res.headerSent"更改为 "res.headersSent"。
"app.route"现在可用于“app.mountpath"。
`res.on('header')`删除。
`res.charset`删除。
`res.setHeader('Set-Cookie', val)` - 功能现已受限,仅用于设置基础的 Cookie 值。 如需使用更多功能,请使用 `res.cookie()`。 -
+| Object | 描述 | +| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| Node.js | Express 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x. | +| `http.createServer()` | The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). 可通过 `app.listen()` 函数启动应用。 | +| `app.configure()` | `app.configure()` 函数已被删除。使用 `process.env.NODE_ENV` 或 `app.get('env)` 函数检测环境并相应配置应用程序。 | +| `json spaces` | Express 4默认禁用了 "json spaces" 应用程序属性。 | +| `req.accepted()` | 使用`req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, 和 `req.acceptsLanguages()`. | +| `res.location()` | No longer resolves relative URLs. | +| `req.params` | Was an array; now an object. | +| `res.locals` | Was a function; now an object. | +| `res.headerSent` | Changed to `res.headersSent`. | +| `app.route` | Now available as `app.mountpath`. | +| `res.on('header')` | Removed. | +| `res.charset` | Removed. | +| `res.setHeader('Set-Cookie', val)` | 功能现已受限,仅用于设置基础的 Cookie 值。 Use `res.cookie()` for added functionality. | ## 应用迁移示例 -以下是将 Express 3 应用迁移至 Express 4 的示例。 -需要关注的文件是 `app.js` 和 `package.json`。 +以下是将 Express 3 应用迁移至 Express 4 的示例。需要关注的文件是 `app.js` 和 `package.json`。 ### 版本 3 应用 @@ -464,10 +298,9 @@ http.createServer(app).listen(app.get('port'), () => { 对 `app.js` 进行如下修改: -1. Express 内置中间件函数 `express.favicon`、`express.logger`、`express.methodOverride`、`express.session`、`express.bodyParser` 和 `express.errorHandler` 已从 `express` 对象中移除。 你必须手动安装它们的替代模块,并在应用中引入加载。 +1. Express 内置中间件函数 `express.favicon`、`express.logger`、`express.methodOverride`、`express.session`、`express.bodyParser` 和 `express.errorHandler` 已从 `express` 对象中移除。你必须手动安装它们的替代模块,并在应用中引入加载。 -2. 你不再需要加载 `app.router` 函数。 - 它并非有效的 Express 4 应用对象,因此请删除 `app.use(app.router); `代码。 +2. 你不再需要加载 `app.router` 函数。它并非有效的 Express 4 应用对象,因此请删除 `app.use(app.router); `代码。 3. 确保中间件函数按正确顺序加载——在应用路由加载完毕后再加载`errorHandler`。 @@ -615,7 +448,7 @@ app.listen(app.get('port'), () => { ### 运行应用 -迁移流程已完成,当前应用已升级为 Express 4 应用。 若要确认,请使用以下命令启动应用: +迁移流程已完成,当前应用已升级为 Express 4 应用。若要确认,请使用以下命令启动应用: ```bash $ node . @@ -671,9 +504,9 @@ $ npm start 查看 `package.json` 文件中的 `npm start` 脚本,你会发现启动应用的实际命令是 `node ./bin/www`,而在 Express 3 中该命令为 `node app.js`。 -由于 Express 4 生成器生成的 `app.js` 文件现已成为一个 Node.js 模块,因此无法再作为应用独立启动(除非你修改代码)。 必须将该模块加载到 Node.js 文件中,并通过该文件启动应用。 在本例中,这个 Node.js 文件就是 `./bin/www`。 +由于 Express 4 生成器生成的 `app.js` 文件现已成为一个 Node.js 模块,因此无法再作为应用独立启动(除非你修改代码)。必须将该模块加载到 Node.js 文件中,并通过该文件启动应用。在本例中,这个 Node.js 文件就是 `./bin/www`。 -创建或启动 Express 应用时,`bin` 目录和无后缀的 `www` 文件都不是必需的。 这些仅为生成器给出的建议,你可按需自行修改。 +创建或启动 Express 应用时,`bin` 目录和无后缀的 `www` 文件都不是必需的。这些仅为生成器给出的建议,你可按需自行修改。 若要移除 `www` 目录并沿用“Express 3 风格”,请删除 `app.js` 文件末尾的 `module.exports = app;` 这一行,然后将以下代码粘贴到该位置: @@ -693,4 +526,4 @@ var debug = require('debug')('app4'); 接下来,将 `package.json` 文件中的 `"start": "node ./bin/www"` 改为 `"start": "node app.js"`。 -你现已将 `./bin/www` 的功能移回至 `app.js`。 不推荐进行此项修改,但该实操能帮你理解 `./bin/www` 文件的工作原理,以及 `app.js` 无法独立启动的原因。 +你现已将 `./bin/www` 的功能移回至 `app.js`。不推荐进行此项修改,但该实操能帮你理解 `./bin/www` 文件的工作原理,以及 `app.js` 无法独立启动的原因。 diff --git a/src/content/pages/zh-cn/guide/migrating-5.mdx b/src/content/pages/zh-cn/guide/migrating-5.mdx index cb83da3cbc..30fe5934f3 100644 --- a/src/content/pages/zh-cn/guide/migrating-5.mdx +++ b/src/content/pages/zh-cn/guide/migrating-5.mdx @@ -6,15 +6,15 @@ description: Express.js 应用从 4 版升级至 5 版完整迁移指南,详 import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; -Express 5 与 Express 4 差异不大;尽管基础 API 保持一致,但仍存在部分导致无法向下兼容的改动。 因此,基于 Express 4 构建的应用在升级至 Express 5 后可能无法正常运行。 +Express 5 与 Express 4 差异不大;尽管基础 API 保持一致,但仍存在部分导致无法向下兼容的改动。因此,基于 Express 4 构建的应用在升级至 Express 5 后可能无法正常运行。 ## 安装 -安装该版本需要 **Node.js 18 及以上版本**。 随后在应用目录中执行以下命令: +安装该版本需要 **Node.js 18 及以上版本**。随后在应用目录中执行以下命令: -随后你可以运行自动化测试来排查失败项,并根据下方列出的更新内容修复问题。 解决测试失败问题后,运行应用查看出现的错误。 你可以立刻发现应用是否使用了任何不受支持的方法或属性。 +随后你可以运行自动化测试来排查失败项,并根据下方列出的更新内容修复问题。解决测试失败问题后,运行应用查看出现的错误。你可以立刻发现应用是否使用了任何不受支持的方法或属性。 ## Express 5 Codemods @@ -32,13 +32,13 @@ Express 5 与 Express 4 差异不大;尽管基础 API 保持一致,但仍存 ## 移除方法和属性 -如果你的应用中使用了上述任意方法或属性,应用将会崩溃。 因此,更新到 5 版本后,你需要修改你的应用。 +如果你的应用中使用了上述任意方法或属性,应用将会崩溃。因此,更新到 5 版本后,你需要修改你的应用。 ### app.del() -Express 5 不再支持 `app.del()` 函数。 如果您使用此函数,将会出现错误。 要注册 HTTP DELETE 路由,请使用 `app.delete()` 函数。 +Express 5 不再支持 `app.del()` 函数。如果您使用此函数,将会出现错误。要注册 HTTP DELETE 路由,请使用 `app.delete()` 函数。 -起初,使用 `del` 而非 `delete`,因为 `delete` 是 JavaScript 中的保留关键字。 但从 ECMAScript 6 开始,`delete` 及其他保留关键字可以合法用作属性名。 +起初,使用 `del` 而非 `delete`,因为 `delete` 是 JavaScript 中的保留关键字。但从 ECMAScript 6 开始,`delete` 及其他保留关键字可以合法用作属性名。 #### 如何更新 @@ -57,11 +57,11 @@ Express 5 不再支持 `app.del()` 函数。 如果您使用此函数,将会 ### app.param(fn) -`app.param(fn)` 签名用于修改 `app.param(name, fn)` 函数的行为。 该方法自 v4.11.0 起已被弃用,Express 5 完全不再支持它。 +`app.param(fn)` 签名用于修改 `app.param(name, fn)` 函数的行为。该方法自 v4.11.0 起已被弃用,Express 5 完全不再支持它。 ### 复数形式的方法名 -以下方法名已改为复数形式。 在 Express 4 中,使用旧方法会触发弃用警告。 Express 5 已完全不再支持这些方法: +以下方法名已改为复数形式。在 Express 4 中,使用旧方法会触发弃用警告。 Express 5 已完全不再支持这些方法: `req.acceptsCharset()`替换为`req.acceptsets()`。 @@ -98,7 +98,7 @@ This should not affect your code if you follow the Express 4 documentation of [a ### req.param(name) -这种可能造成混淆且存在风险的表单数据获取方法已被移除。 现在你需要在 `req.params`、`req.body` 或 `req.query` 对象中显式查找提交的参数名称。 +这种可能造成混淆且存在风险的表单数据获取方法已被移除。现在你需要在 `req.params`、`req.body` 或 `req.query` 对象中显式查找提交的参数名称。 #### 如何更新 @@ -123,7 +123,7 @@ This should not affect your code if you follow the Express 4 documentation of [a ### res.json(obj, status) -Express 5 不再支持 `res.json(obj, status)` 签名。 取而代之的是,先设置状态码,再链式调用 `res.json()` 方法,写法如下:`res.status(status).json(obj)`。 +Express 5 不再支持 `res.json(obj, status)` 签名。取而代之的是,先设置状态码,再链式调用 `res.json()` 方法,写法如下:`res.status(status).json(obj)`。 #### 如何更新 @@ -142,7 +142,7 @@ Express 5 不再支持 `res.json(obj, status)` 签名。 取而代之的是, ### res.jsonp(obj, status) -Express 5 不再支持 `res.jsonp(obj, status)` 签名。 取而代之的是,先设置状态码,再链式调用 `res.jsonp()` 方法,写法如下:`res.status(status).jsonp(obj)`。 +Express 5 不再支持 `res.jsonp(obj, status)` 签名。取而代之的是,先设置状态码,再链式调用 `res.jsonp()` 方法,写法如下:`res.status(status).jsonp(obj)`。 #### 如何更新 @@ -161,7 +161,7 @@ Express 5 不再支持 `res.jsonp(obj, status)` 签名。 取而代之的是, ### res.redirect(url, status) -Express 5 不再支持 `res.redirect(url, status)` 签名。 相反,使用下列签名:`res.redirect(status, url)`。 +Express 5 不再支持 `res.redirect(url, status)` 签名。相反,使用下列签名:`res.redirect(status, url)`。 #### 如何更新 @@ -185,7 +185,7 @@ Express 5 不再支持 `res.redirect(url, status)` 签名。 相反,使用下 ### res.redirect('back') 与 res.location('back') -Express 5 不再支持 `res.redirect()` 和 `res.location()` 方法中的魔法字符串 `back`。 取而代之,请使用 `req.get('Referrer') || '/'` 来重定向回上一页。 在 Express 4 中,`res.redirect('back')` 和 `res.location('back')` 方法已被弃用。 +Express 5 不再支持 `res.redirect()` 和 `res.location()` 方法中的魔法字符串 `back`。取而代之,请使用 `req.get('Referrer') || '/'` 来重定向回上一页。在 Express 4 中,`res.redirect('back')` 和 `res.location('back')` 方法已被弃用。 #### 如何更新 @@ -204,7 +204,7 @@ Express 5 不再支持 `res.redirect()` 和 `res.location()` 方法中的魔法 ### res.send(body, status) -Express 5 不再支持 `res.send(obj, status)` 这种签名。 取而代之的是,先设置状态码,再链式调用 `res.send()` 方法,写法如下:`res.status(status).send(obj)`。 +Express 5 不再支持 `res.send(obj, status)` 这种签名。取而代之的是,先设置状态码,再链式调用 `res.send()` 方法,写法如下:`res.status(status).send(obj)`。 #### 如何更新 @@ -223,8 +223,7 @@ Express 5 不再支持 `res.send(obj, status)` 这种签名。 取而代之的 ### res.send(status) -Express 5 不再支持签名 `res.send(status)` 是一个数字。 取而代之,请使用 `res.sendStatus(statusCode)` 函数,该函数会设置 HTTP 响应头状态码并发送该状态码的文本版本:“未找到”、“服务器内部错误”等。 -如果需要通过 `res.send()` 函数发送数字,请将数字用引号包裹转换为字符串,避免 Express 将其误判为尝试使用已不支持的旧签名。 +Express 5 不再支持签名 `res.send(status)` 是一个数字。取而代之,请使用 `res.sendStatus(statusCode)` 函数,该函数会设置 HTTP 响应头状态码并发送该状态码的文本版本:“未找到”、“服务器内部错误”等。如果需要通过 `res.send()` 函数发送数字,请将数字用引号包裹转换为字符串,避免 Express 将其误判为尝试使用已不支持的旧签名。 #### 如何更新 @@ -262,7 +261,7 @@ Express 5 不再支持签名 `res.send(status)` 是一个数字。 取而代之 ### res.sendFile() options -`res.sendFile()` 的 `hidden` 和 `from` 选项已不再支持。 使用 `dotfiles` 和 `root` 代替。 +`res.sendFile()` 的 `hidden` 和 `from` 选项已不再支持。使用 `dotfiles` 和 `root` 代替。 The `dotfiles` option applies to hidden directories in the path as well as hidden files. For example, a file served from an absolute path like `/var/www/app/.cache/index.html` now requires `dotfiles: 'allow'`, even though `index.html` is not a dotfile. In Express 4 a hidden directory in the path was served by default; Express 5 returns `404` unless you opt in. @@ -295,7 +294,7 @@ If you serve an absolute path that contains a hidden directory, opt in with `dot ### express.static() options -不再支持 `expres.static()` 的 `hidden` 和 `from` 两个选项。 使用 `dotfiles` 和 `root` 代替。 注意,`from` 从未在 API 文档中记载,但曾被接受作为 `root` 的别名。 `dotfiles`的默认值现在是 \`"ignore"。 +不再支持 `expres.static()` 的 `hidden` 和 `from` 两个选项。使用 `dotfiles` 和 `root` 代替。注意,`from` 从未在 API 文档中记载,但曾被接受作为 `root` 的别名。 `dotfiles`的默认值现在是 \`"ignore"。 The `dotfiles` check now also applies to hidden **directories** in the request path, not just hidden files. A request like `GET /.well-known/acme-challenge/...` that was served by default in Express 4 now returns `404` unless you set `dotfiles: 'allow'`. This only affects the part of the path relative to the configured `root`; a hidden directory in `root` itself is unaffected. @@ -324,12 +323,11 @@ If you rely on serving a hidden directory such as `.well-known` (for example, AC ### router.param(fn) -`router.param(fn)` 签名曾用于修改 `router.param(name, fn)` 函数的行为。 该方法自 v4.11.0 起已被弃用,Express 5 完全不再支持它。 +`router.param(fn)` 签名曾用于修改 `router.param(name, fn)` 函数的行为。该方法自 v4.11.0 起已被弃用,Express 5 完全不再支持它。 ### express.static.mime -在 Express 5 中,`mime` 不再是 `static` 字段的导出属性。 -请使用 [`mime-types` 包](https://github.com/jshttp/mime-types) 处理 MIME 类型值。 +在 Express 5 中,`mime` 不再是 `static` 字段的导出属性。请使用 [`mime-types` 包](https://github.com/jshttp/mime-types) 处理 MIME 类型值。 #### 如何更新 @@ -347,15 +345,15 @@ If you rely on serving a hidden directory such as `.well-known` (for example, AC ### MIME 类型更改 -由于[`mime-db`](https://github.com/jshttp/mime-db) 的更新,几种MIME类型已经更改。 这些更改只会影响 `expres.static()` 和 `res.sendFile()` 。 完整的更改列表见[`mime-db`更新日志](https://github.com/jshttp/mime-db/blob/HEAD/HISTORY.md)。 +由于[`mime-db`](https://github.com/jshttp/mime-db) 的更新,几种MIME类型已经更改。这些更改只会影响 `expres.static()` 和 `res.sendFile()` 。完整的更改列表见[`mime-db`更新日志](https://github.com/jshttp/mime-db/blob/HEAD/HISTORY.md)。 -Express 4 使用 **1.52.0** 版本的 `mime-db`,而 Express 5 使用了更新的版本,以反映 IANA 及其他 MIME 类型规范的更新。 最显著的变化是,JavaScript 文件(`.js`)现在以 `text/javascript` 提供服务,而非 `application/javascript`。 +Express 4 使用 **1.52.0** 版本的 `mime-db`,而 Express 5 使用了更新的版本,以反映 IANA 及其他 MIME 类型规范的更新。最显著的变化是,JavaScript 文件(`.js`)现在以 `text/javascript` 提供服务,而非 `application/javascript`。 在 Express 5 中,由 `mime-db` 更新带来的 MIME 类型变更**不被视为破坏性变更**,因此在更新依赖项时请务必谨慎,因为 MIME 类型可能在次要版本或补丁版本之间发生变化。 ### express:router 调试日志 -路由器处理逻辑现在由 Express 团队维护的独立依赖项([`router`](https://github.com/pillarjs/router))执行,因此调试日志已迁移至其他命名空间。 在Express 5.1之前,这些调试日志不存在。 若要获取这些日志,请更新至最新的 Express 5 版本,或更新 `package-lock.json` 中的 `router` 包: +路由器处理逻辑现在由 Express 团队维护的独立依赖项([`router`](https://github.com/pillarjs/router))执行,因此调试日志已迁移至其他命名空间。在Express 5.1之前,这些调试日志不存在。若要获取这些日志,请更新至最新的 Express 5 版本,或更新 `package-lock.json` 中的 `router` 包: | v4 | v5 | | -------------------------- | ----------------------------------- | @@ -373,11 +371,11 @@ Express 4 使用 **1.52.0** 版本的 `mime-db`,而 Express 5 使用了更新 ## 更改 -这些 API 仍然保留,但行为已发生变更。 请检查这些变更,确保你的应用正常运行。 +这些 API 仍然保留,但行为已发生变更。请检查这些变更,确保你的应用正常运行。 ### 路径路由匹配语法 -路径路由匹配语法是指将字符串作为第一个参数传递给 `app.all()`、`app.use()`、`app.METHOD()`、`router.all()`、`router.METHOD()` 和 `router.use()` 这些 API。 已对路径字符串与传入请求的匹配规则做出如下修改: +路径路由匹配语法是指将字符串作为第一个参数传递给 `app.all()`、`app.use()`、`app.METHOD()`、`router.all()`、`router.METHOD()` 和 `router.use()` 这些 API。已对路径字符串与传入请求的匹配规则做出如下修改: - 通配符 `*` 必须指定名称,和参数标记 `:` 的使用规则保持一致,请使用 `/*splat` 而非 `/*` @@ -390,7 +388,7 @@ Express 4 使用 **1.52.0** 版本的 `mime-db`,而 Express 5 使用了更新 - `*splat` 匹配没有根路径的任何路径。 如果你需要同时匹配根路径,你可以使用 `/{*splat}` 来包装括号中的通配符。 + `*splat` 匹配没有根路径的任何路径。如果你需要同时匹配根路径,你可以使用 `/{*splat}` 来包装括号中的通配符。 ```js app.get('/{*splat}', async (req, res) => { @@ -409,7 +407,7 @@ Express 4 使用 **1.52.0** 版本的 `mime-db`,而 Express 5 使用了更新 }); ``` -- 路由路径中不支持正则表达式字符。 举个例子: +- 路由路径中不支持正则表达式字符。举个例子: ```diff -app.get('/[discussion|page]/:slug', async (req, res) => { @@ -424,13 +422,13 @@ Express 4 使用 **1.52.0** 版本的 `mime-db`,而 Express 5 使用了更新 ### 处理来自中间件和处理器的被拒绝 Promise -返回被拒绝 Promise 的请求中间件和处理程序,现会将被拒绝的值作为 `Error` 转发给错误处理中间件进行处理。 这意味着使用 `async` 函数编写中间件和处理程序变得前所未有的简便。 当在 `async` 函数中抛出错误,或在异步函数内 `await` 了一个被拒绝的 Promise 时,这些错误将被传递给错误处理程序,效果等同于调用 `next(err)`。 +返回被拒绝 Promise 的请求中间件和处理程序,现会将被拒绝的值作为 `Error` 转发给错误处理中间件进行处理。这意味着使用 `async` 函数编写中间件和处理程序变得前所未有的简便。当在 `async` 函数中抛出错误,或在异步函数内 `await` 了一个被拒绝的 Promise 时,这些错误将被传递给错误处理程序,效果等同于调用 `next(err)`。 Details of how Express handles errors is covered in the [error handling documentation](/guide/error-handling). #### 如何更新 -你现在可以直接使用 `async/await`,无需手动捕获错误。 若 `getUserById` 抛出错误或被拒绝,`next` 会自动以被拒绝的值作为参数被调用。 +你现在可以直接使用 `async/await`,无需手动捕获错误。若 `getUserById` 抛出错误或被拒绝,`next` 会自动以被拒绝的值作为参数被调用。 ```diff -app.get('/user/:id', (req, res, next) => { @@ -459,11 +457,11 @@ Details of how Express handles errors is covered in the [error handling document ### express.static dotfiles -`express.static` 中间件的 `dotfiles` 选项现在默认值为 `"ignore"`。 在 Express 4 中,点文件默认提供服务。 因此,以点(`.`)开头的目录(如 `.well-known`)内的文件将不再可访问,并会返回**404 未找到**错误。 这可能会破坏依赖于提供点目录服务的功能,例如 Android 应用链接和 Apple 通用链接。 +`express.static` 中间件的 `dotfiles` 选项现在默认值为 `"ignore"`。在 Express 4 中,点文件默认提供服务。因此,以点(`.`)开头的目录(如 `.well-known`)内的文件将不再可访问,并会返回**404 未找到**错误。这可能会破坏依赖于提供点目录服务的功能,例如 Android 应用链接和 Apple 通用链接。 #### 如何更新 -使用 `dotfiles: "allow"` 选项显式提供特定的点目录服务。 这使你可以安全地仅提供预期的点目录,同时对其他点文件保持默认的安全行为。 +使用 `dotfiles: "allow"` 选项显式提供特定的点目录服务。这使你可以安全地仅提供预期的点目录,同时对其他点文件保持默认的安全行为。 ```diff +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })); @@ -491,8 +489,7 @@ Register each parameter name with its own `router.param()` call: ### app.listen -在 Express 5 中,当服务器接收到错误事件时,`app.listen` 方法会调用用户提供的回调函数(若已指定)。 在 Express 4 中,这类错误会被直接抛出。 在 Express 5 中,此项变更将错误处理的职责转移给了回调函数。 如果发生错误,错误将作为参数传递给回调函数。 -举个例子: +在 Express 5 中,当服务器接收到错误事件时,`app.listen` 方法会调用用户提供的回调函数(若已指定)。在 Express 4 中,这类错误会被直接抛出。在 Express 5 中,此项变更将错误处理的职责转移给了回调函数。如果发生错误,错误将作为参数传递给回调函数。举个例子: ```js ins={2-4} const server = app.listen(8080, '0.0.0.0', (error) => { @@ -505,11 +502,11 @@ const server = app.listen(8080, '0.0.0.0', (error) => { ### app.router -在 Express 4 中被移除的 `app.router` 对象,在 Express 5 中重新回归。 在新版本中,该对象只是对基础 Express 路由的引用,这与 Express 3 不同,在 Express 3 中应用必须显式加载它。 +在 Express 4 中被移除的 `app.router` 对象,在 Express 5 中重新回归。在新版本中,该对象只是对基础 Express 路由的引用,这与 Express 3 不同,在 Express 3 中应用必须显式加载它。 ### req.body -当请求体尚未被解析时,`req.body` 属性会返回 `undefined`。 在Express 4中,默认情况下返回 `{}` 。 +当请求体尚未被解析时,`req.body` 属性会返回 `undefined`。在Express 4中,默认情况下返回 `{}` 。 ```js del={4} ins={6} app.post('/user', (req, res) => { @@ -527,7 +524,7 @@ app.post('/user', (req, res) => { ### req.params -当使用字符串路径时,`req.params`对象现在有一个 **null 原型** 。 但是,如果路径使用正则表达式定义,`req.params` 仍为带有标准原型的普通对象。 此外,还有两项重要的行为变更: +当使用字符串路径时,`req.params`对象现在有一个 **null 原型** 。但是,如果路径使用正则表达式定义,`req.params` 仍为带有标准原型的普通对象。此外,还有两项重要的行为变更: **WildCard 参数现在是数组:** @@ -543,7 +540,7 @@ app.get('/*splat', (req, res) => { **未匹配参数:** -在 Express 4 中,不匹配的通配符为空字符串(`''`),可选 `:` 参数(使用 `?`)会存在键且值为 `undefined`。 在 Express 5 中,不匹配的参数会从 `req.params` 中完全省略。 +在 Express 4 中,不匹配的通配符为空字符串(`''`),可选 `:` 参数(使用 `?`)会存在键且值为 `undefined`。在 Express 5 中,不匹配的参数会从 `req.params` 中完全省略。 ```diff -// v4: unmatched wildcard is empty string @@ -570,7 +567,7 @@ app.get('/*splat', (req, res) => { ### req.query -`req.query` 属性不再是可写属性,而是一个 getter。 默认查询解析器已从 "extended" 更改为 "simple"。 +`req.query` 属性不再是可写属性,而是一个 getter。默认查询解析器已从 "extended" 更改为 "simple"。 ```js del={3} app.get('/search', (req, res) => { @@ -603,7 +600,7 @@ app.get('/user', (req, res) => { ### res.vary -当缺少`field`参数时,`res.vary`会抛出错误。 在 Express 4 中,如果省略该参数,控制台会输出一条警告信息。 +当缺少`field`参数时,`res.vary`会抛出错误。在 Express 4 中,如果省略该参数,控制台会输出一条警告信息。 ```js del={2} app.get('/user', (req, res) => { diff --git a/src/content/pages/zh-cn/resources/community.mdx b/src/content/pages/zh-cn/resources/community.mdx index f0aa376e8e..c4fc2f78e7 100644 --- a/src/content/pages/zh-cn/resources/community.mdx +++ b/src/content/pages/zh-cn/resources/community.mdx @@ -7,7 +7,7 @@ import LogoDisplay from '@components/patterns/LogoDisplay/LogoDisplay.astro'; ## 技术委员会 -Express技术委员会每两周按需召开线上会议,研讨Express的开发、维护工作以及项目相关的其他事宜。 每次会议通常会在[expressjs/discussions 议题](https://github.com/expressjs/discussions/issues)中发布通知,附带参会或旁听链接,所有人员均可列席观摩。 +Express技术委员会每两周按需召开线上会议,研讨Express的开发、维护工作以及项目相关的其他事宜。每次会议通常会在[expressjs/discussions 议题](https://github.com/expressjs/discussions/issues)中发布通知,附带参会或旁听链接,所有人员均可列席观摩。 会议全程录播,可前往 [Express.js YouTube 频道](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g)查看录播列表。 @@ -58,7 +58,7 @@ Our vibrant community has created a large variety of extensions, ## Express.js Logo -Express 是 OpenJS 基金会旗下项目。 如需了解Express.js标识与商标的合规使用规范,请查阅[商标使用规范](https://trademark-policy.openjsf.org/)。 +Express 是 OpenJS 基金会旗下项目。如需了解Express.js标识与商标的合规使用规范,请查阅[商标使用规范](https://trademark-policy.openjsf.org/)。 ### Wordmark diff --git a/src/content/pages/zh-cn/resources/contributing.mdx b/src/content/pages/zh-cn/resources/contributing.mdx index 6579b1d504..ac1a14f5ad 100644 --- a/src/content/pages/zh-cn/resources/contributing.mdx +++ b/src/content/pages/zh-cn/resources/contributing.mdx @@ -5,7 +5,7 @@ description: 了解如何为 Express.js 贡献代码,包含提交问题、发 import Alert from '@components/primitives/Alert/Alert.astro'; -Express 是隶属于 [OpenJS 基金会](https://openjsf.org/)的项目,相关代码分散在三个 GitHub 组织:[expressjs](https://github.com/expressjs)、[pillarjs](https://github.com/pillarjs) 与 [jshttp](https://github.com/jshttp)。 无论是反馈漏洞、完善文档还是提交代码,我们都欢迎各类贡献。 下述规范说明了项目运作方式以及你的参与途径。 +Express 是隶属于 [OpenJS 基金会](https://openjsf.org/)的项目,相关代码分散在三个 GitHub 组织:[expressjs](https://github.com/expressjs)、[pillarjs](https://github.com/pillarjs) 与 [jshttp](https://github.com/jshttp)。无论是反馈漏洞、完善文档还是提交代码,我们都欢迎各类贡献。下述规范说明了项目运作方式以及你的参与途径。 ## 技术委员会 @@ -32,33 +32,32 @@ Express 技术委员会由项目在职成员组成,负责统筹 Express 项目 ### 提交问题反馈 -如有疑问或遇到问题,均可提交议题。 拿不准时直接提交议题即可,回复中会补充所需填写内容的相关规范。 唯一例外是安全漏洞披露,此类内容需私下提交。 +如有疑问或遇到问题,均可提交议题。拿不准时直接提交议题即可,回复中会补充所需填写内容的相关规范。唯一例外是安全漏洞披露,此类内容需私下提交。 提交者可引导你跳转至其他代码仓库、要求补充说明,并在处理议题前添加相应元数据。 -请保持礼貌、友善交流。 所有参与者均须遵守项目行为准则。 +请保持礼貌、友善交流。所有参与者均须遵守项目行为准则。 ### 代码贡献 -本仓库内所有资源修改均须通过拉取请求提交。 该规则适用于文档、代码、二进制文件等全部内容的修改。 即便是资深提交者与技术委员会成员,修改代码也必须提交拉取请求。 +本仓库内所有资源修改均须通过拉取请求提交。该规则适用于文档、代码、二进制文件等全部内容的修改。即便是资深提交者与技术委员会成员,修改代码也必须提交拉取请求。 所有拉取请求未经评审不得合并。 -对于重要改动类贡献,拉取请求至少留置36小时,保障其他时区的贡献者有充足时间完成评审。 同时需兼顾周末与法定节假日,确保在岗提交者若有意参与,都能拥有充裕时间投入讨论与评审工作。 +对于重要改动类贡献,拉取请求至少留置36小时,保障其他时区的贡献者有充足时间完成评审。同时需兼顾周末与法定节假日,确保在岗提交者若有意参与,都能拥有充裕时间投入讨论与评审工作。 -若无提交者提出异议,该贡献默认予以接纳。 -评审期间,提交者可指定对应领域的资深贡献者给出 **LGTM(核准通过)** 评语后,方可合并该拉取请求。 代码合入无需额外签署确认流程。 提交者提出的所有问题整改完毕后,任意一名提交者均可合入该变更。 +若无提交者提出异议,该贡献默认予以接纳。评审期间,提交者可指定对应领域的资深贡献者给出 **LGTM(核准通过)** 评语后,方可合并该拉取请求。代码合入无需额外签署确认流程。提交者提出的所有问题整改完毕后,任意一名提交者均可合入该变更。 若有其他提交者对拉取请求提出异议,所有相关提交者应通过沟通商榷、对方案折中调整或撤回变更提案等方式处理分歧,力求达成共识。 -若某项贡献存在较大争议,提交者无法就变更能否合入、如何合入达成统一意见,则需将问题上报至技术委员会(TC)裁决。 技术委员会成员需定期研讨待处理的贡献内容,敲定解决方案。 仅极少数争议议题才需交由技术委员会裁定,提交者间沟通协商、折中处理是常规解决方式。 +若某项贡献存在较大争议,提交者无法就变更能否合入、如何合入达成统一意见,则需将问题上报至技术委员会(TC)裁决。技术委员会成员需定期研讨待处理的贡献内容,敲定解决方案。仅极少数争议议题才需交由技术委员会裁定,提交者间沟通协商、折中处理是常规解决方式。 ### 成为问题分拣者 任何人都可以成为问题分拣员! Read more about the process of being a triager in [the triage process document](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/triager-guide.md). -目前,项目组织内任一现有成员均可提名新任问题分拣员。 如果你有意成为问题分拣员,我们的建议是积极参与社区,协助梳理问题与拉取请求。 同时也建议参与其他社区活动,例如列席技术委员会会议、在 Slack 群组参与交流讨论。 若你已积累一定的工单分拣实操经验、自认条件成熟,可联系项目在职组织成员,征询对方是否愿意提名举荐你。 若对方同意,可提交拉取请求正式确定提名。 如对提名存有异议,筛选小组负责与相关人员协作并寻求解决方案。 +目前,项目组织内任一现有成员均可提名新任问题分拣员。如果你有意成为问题分拣员,我们的建议是积极参与社区,协助梳理问题与拉取请求。同时也建议参与其他社区活动,例如列席技术委员会会议、在 Slack 群组参与交流讨论。若你已积累一定的工单分拣实操经验、自认条件成熟,可联系项目在职组织成员,征询对方是否愿意提名举荐你。若对方同意,可提交拉取请求正式确定提名。如对提名存有异议,筛选小组负责与相关人员协作并寻求解决方案。 如有疑问或需要指导,你也可以联系任意一位[组织成员](https://github.com/orgs/expressjs/people)。 @@ -70,36 +69,31 @@ Express 技术委员会由项目在职成员组成,负责统筹 Express 项目 ### 技术委员会流程 -对于提交至技术委员会的议题,委员会采用「寻求共识」流程处理。 -小组力求拿出一项无技术委员会成员提出异议的解决方案。 -若无法达成全无异议的共识,则启动多数票决制。 技术委员会的多数决议应当通过寻求共识流程敲定,投票仅作为最终备选方案。 +对于提交至技术委员会的议题,委员会采用「寻求共识」流程处理。小组力求拿出一项无技术委员会成员提出异议的解决方案。若无法达成全无异议的共识,则启动多数票决制。技术委员会的多数决议应当通过寻求共识流程敲定,投票仅作为最终备选方案。 -决议可附带推进共识的相关建议,将议题退回项目负责人处理。 技术委员会会议无需在当次会议解决议程内全部议题,可选择交由项目负责人继续研讨。 +决议可附带推进共识的相关建议,将议题退回项目负责人处理。技术委员会会议无需在当次会议解决议程内全部议题,可选择交由项目负责人继续研讨。 -可随时增补技术委员会成员。 任意一名技术委员会成员均可提名其他提交者加入委员会,委员会将按照常规的寻求共识流程审议是否吸纳该新成员。 技术委员会常设成员最少3人、最多10人。 若技术委员会在册成员不足5人,在职委员需提名新成员。 技术委员会成员离任时,鼓励(非强制)其提名继任人选。 +可随时增补技术委员会成员。任意一名技术委员会成员均可提名其他提交者加入委员会,委员会将按照常规的寻求共识流程审议是否吸纳该新成员。技术委员会常设成员最少3人、最多10人。若技术委员会在册成员不足5人,在职委员需提名新成员。技术委员会成员离任时,鼓励(非强制)其提名继任人选。 TC members will be added as admin's on the Github orgs, npm orgs, and other resources as necessary to be effective in the role. -若要保持在职状态,技术委员会成员需在近12个月内参与相关工作,且连续缺席委员会会议不得超过六次。 本准则旨在提升成员参与度,而非对参与不足的人员进行惩处,仅用于如以新任活跃成员替换长期怠职成员等场景。 未达到上述任职要求的委员应当主动卸任。 若相关委员拒不主动卸任,可在讨论仓库新建议题,提请将其转为非在职状态。 因主动离任或履职不足被免去职务的技术委员会成员,将转为非活跃委员身份。 +若要保持在职状态,技术委员会成员需在近12个月内参与相关工作,且连续缺席委员会会议不得超过六次。本准则旨在提升成员参与度,而非对参与不足的人员进行惩处,仅用于如以新任活跃成员替换长期怠职成员等场景。未达到上述任职要求的委员应当主动卸任。若相关委员拒不主动卸任,可在讨论仓库新建议题,提请将其转为非在职状态。因主动离任或履职不足被免去职务的技术委员会成员,将转为非活跃委员身份。 -在委员会总人数未超出10人上限的前提下,非活跃委员可通过自荐重新转为在职委员。 若委员会已满员,现有在职成员离任时,非活跃成员拥有优先补位资格。 +在委员会总人数未超出10人上限的前提下,非活跃委员可通过自荐重新转为在职委员。若委员会已满员,现有在职成员离任时,非活跃成员拥有优先补位资格。 ### 项目负责人 -Express技术委员会可为本组织下各个项目/代码仓库指定项目负责人。 这些负责人作为对应代码仓库的日常核心维护者,全权负责仓库的技术运维与社区相关事务。 -仓库负责人拥有对应仓库所有者权限以及软件包发布权限。 -出现分歧(尤其是波及整个Express项目的重大事项)时,项目负责人须上报技术委员会,并牵头推动分歧落地解决。 负责人同时负责督促社区成员遵守社区规范、维护代码仓库与已发布软件包,并为用户提供技术支持。 +Express技术委员会可为本组织下各个项目/代码仓库指定项目负责人。这些负责人作为对应代码仓库的日常核心维护者,全权负责仓库的技术运维与社区相关事务。仓库负责人拥有对应仓库所有者权限以及软件包发布权限。出现分歧(尤其是波及整个Express项目的重大事项)时,项目负责人须上报技术委员会,并牵头推动分歧落地解决。负责人同时负责督促社区成员遵守社区规范、维护代码仓库与已发布软件包,并为用户提供技术支持。 和技术委员会成员一样,仓库负责人从提交者中遴选产生。 -拟任项目负责人者,在提出任职申请前,需已以提交者身份参与该项目维护满6个月。 候选人需参与代码提交,并协助问题分类处理工作。 候选人须在其 GitHub 与 npm 账号上均开启双重认证(2FA)。 +拟任项目负责人者,在提出任职申请前,需已以提交者身份参与该项目维护满6个月。候选人需参与代码提交,并协助问题分类处理工作。候选人须在其 GitHub 与 npm 账号上均开启双重认证(2FA)。 -同一仓库的现任技术委员会成员或仓库负责人,均可提名其他提交者出任仓库负责人。 提名时需针对本文档提交拉取请求(PR),在**在职项目负责人**板块(保持原有排序不变)补充项目名称、被提名人的GitHub账号,以及其npm用户名(二者不一致时需填写)。 +同一仓库的现任技术委员会成员或仓库负责人,均可提名其他提交者出任仓库负责人。提名时需针对本文档提交拉取请求(PR),在**在职项目负责人**板块(保持原有排序不变)补充项目名称、被提名人的GitHub账号,以及其npm用户名(二者不一致时需填写)。 - 各仓库可根据实际工作量灵活设置多名项目负责人。 -- 同一项目的技术委员会成员或现任仓库负责人可提名新任项目负责人。 - 其他项目的仓库负责人无权跨项目提名负责人。 +- 同一项目的技术委员会成员或现任仓库负责人可提名新任项目负责人。其他项目的仓库负责人无权跨项目提名负责人。 PR 需获得至少两名技术委员会成员批准,且设置两周公示期,用于收集意见与异议。 PR合并后,由一名技术委员会成员将新任负责人添加至对应的GitHub与npm权限分组。 @@ -119,11 +113,11 @@ PR 需获得至少两名技术委员会成员批准,且设置两周公示期 #### 例外情形 -任何人因个人或工作原因均可申请暂停履职。 该人员需告知对应工作组或技术委员会(TC)。 在此期间,闲置认定规则暂停生效,该人员不会被标记为闲置。 +任何人因个人或工作原因均可申请暂停履职。该人员需告知对应工作组或技术委员会(TC)。在此期间,闲置认定规则暂停生效,该人员不会被标记为闲置。 #### 闲置处理流程 -- 若人员被认定为闲置,可转为荣誉任职身份,以此认可其过往贡献。 我方会尽可能通知当事人该变动事宜。 待其准备重新履职时,可申请恢复原有职务。 +- 若人员被认定为闲置,可转为荣誉任职身份,以此认可其过往贡献。我方会尽可能通知当事人该变动事宜。待其准备重新履职时,可申请恢复原有职务。 - 荣誉任职身份可留存曾为项目作出重要贡献的贡献者履历记录。 #### 权责说明 @@ -185,14 +179,14 @@ By making a contribution to this project, I certify that: 1. 针对你想要修复的漏洞或新增的功能创建一个议题。 2. 在 GitHub 上创建个人复刻仓库,随后检出该复刻仓库。 -3. 在本地副本中编写代码。 虽然不是强制性要求,但为你处理的每个新议题创建一个分支是一种良好的实践。 +3. 在本地副本中编写代码。虽然不是强制性要求,但为你处理的每个新议题创建一个分支是一种良好的实践。 4. 要运行测试套件,首先通过执行 `npm install` 安装依赖项,然后执行 `npm test`。 5. 通过执行 `npm run lint` 确保你的代码通过代码检查 —fix所有列出的问题。 -6. 如果测试通过,你可以将你的更改提交到你的复刻仓库中,然后创建一个拉取请求。 务必在拉取请求的评论中带上议题编号(例如 `#123`)以关联对应的议题。 +6. 如果测试通过,你可以将你的更改提交到你的复刻仓库中,然后创建一个拉取请求。务必在拉取请求的评论中带上议题编号(例如 `#123`)以关联对应的议题。 ### 咨询类议题 -我们通常会关闭内容含糊不清或仅针对你个人开发项目的咨询类议题。 在随意提交咨询类议题前,请先仔细查阅文档及其他参考资料。 +我们通常会关闭内容含糊不清或仅针对你个人开发项目的咨询类议题。在随意提交咨询类议题前,请先仔细查阅文档及其他参考资料。 有助于你的咨询类议题获得审阅的相关事项: @@ -203,7 +197,7 @@ By making a contribution to this project, I certify that: 若提交咨询类问题,但未列明上述内容、难以让工作人员理解和复现问题,该议题将会被关闭。 -若你的问题满足上述全部条件,但你认为无需项目维护人员介入审阅(例如仅寻求社区意见),请创建讨论帖而非议题。 若拿不准而新建了议题,维护人员在分类处理后,若判定该问题无需高曝光度或官方介入,会将议题迁移至讨论区。 +若你的问题满足上述全部条件,但你认为无需项目维护人员介入审阅(例如仅寻求社区意见),请创建讨论帖而非议题。若拿不准而新建了议题,维护人员在分类处理后,若判定该问题无需高曝光度或官方介入,会将议题迁移至讨论区。 ## 安全策略与处理流程 @@ -224,12 +218,9 @@ By making a contribution to this project, I certify that: -Express 团队与社区高度重视所有安全漏洞问题。 -感谢您助力提升 Express 及其相关项目的安全性。 -感谢您遵循负责任披露原则提交漏洞,我们会尽全力标注致谢您的贡献。 +Express 团队与社区高度重视所有安全漏洞问题。感谢您助力提升 Express 及其相关项目的安全性。感谢您遵循负责任披露原则提交漏洞,我们会尽全力标注致谢您的贡献。 -安全初审组成员(链接:[Security triage team member](https://github.com/expressjs/security-wg#security-triage-team-expressjssecurity-triage))或仓库负责人(链接:[the repo captain](https://github.com/expressjs/discussions/blob/master/docs/contributing/captains_and_committers.md))会尽快确认收到你的漏洞报告。 -若漏洞初审志愿者休假(尤其年末时段),上述处理时限可能相应顺延。 +安全初审组成员(链接:[Security triage team member](https://github.com/expressjs/security-wg#security-triage-team-expressjssecurity-triage))或仓库负责人(链接:[the repo captain](https://github.com/expressjs/discussions/blob/master/docs/contributing/captains_and_committers.md))会尽快确认收到你的漏洞报告。若漏洞初审志愿者休假(尤其年末时段),上述处理时限可能相应顺延。 在初次回复漏洞上报后,安全团队会持续向你同步漏洞修复与正式公告的进展,同时可能会向你索要补充信息或相关说明。 @@ -241,16 +232,14 @@ Express 团队与社区高度重视所有安全漏洞问题。 #### 通过 GitHub 安全通告上报安全漏洞(推荐方式) -上报安全漏洞的首选方式是通过 [GitHub 安全通告](https://github.com/advisories)。 -该方式便于我们在保密漏洞报告的前提下协作完成漏洞修复。 +上报安全漏洞的首选方式是通过 [GitHub 安全通告](https://github.com/advisories)。该方式便于我们在保密漏洞报告的前提下协作完成漏洞修复。 漏洞上报方式(参考文档:[docs](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability)) 1. 在 GitHub 上进入受影响仓库的**安全**标签页。 2. 点击**上报漏洞**并按照指引步骤操作。 -本流程适用于Express生态下的所有代码仓库。 -若无法确定对应仓库是否适用本规范,可通过邮件咨询。 +本流程适用于Express生态下的所有代码仓库。若无法确定对应仓库是否适用本规范,可通过邮件咨询。 #### 通过邮件上报 @@ -258,7 +247,7 @@ Express 团队与社区高度重视所有安全漏洞问题。 如需及时得到回复,请将全部相关信息直接写在邮件正文中,不要使用外链或附件。 -项目主维护人员会在48小时内确认收到邮件,并给出初步回复说明后续处理步骤。 安全团队会同步处理进度,并可能需要你补充相关细节。 +项目主维护人员会在48小时内确认收到邮件,并给出初步回复说明后续处理步骤。安全团队会同步处理进度,并可能需要你补充相关细节。 #### 第三方模块 @@ -266,11 +255,11 @@ Express 团队与社区高度重视所有安全漏洞问题。 ### 披露规范 -安全团队收到安全漏洞报告后,会指派一名主要负责人处理。 该负责人统筹修复与发布流程,包含以下步骤: +安全团队收到安全漏洞报告后,会指派一名主要负责人处理。该负责人统筹修复与发布流程,包含以下步骤: - 确认问题并确定受影响的版本。 - 审核代码以查找所有潜在的同类问题。 -- 为所有仍在维护的版本准备修复方案。 这些修复会尽快发布至npm。 +- 为所有仍在维护的版本准备修复方案。这些修复会尽快发布至npm。 ### 对此规范的意见 @@ -278,8 +267,8 @@ Express 团队与社区高度重视所有安全漏洞问题。 ### Express 威胁模型划 -Express 威胁模型划定了该框架所需承担安全责任的边界范围。 该文档划定了可信主体(如开发者、运行环境、应用代码)与不可信数据源(如网络传输数据)的界定范围。 由可信资源引发的问题不在(框架)负责范围内,而 Express 负责安全处理不可信数据。 +Express 威胁模型划定了该框架所需承担安全责任的边界范围。该文档划定了可信主体(如开发者、运行环境、应用代码)与不可信数据源(如网络传输数据)的界定范围。由可信资源引发的问题不在(框架)负责范围内,而 Express 负责安全处理不可信数据。 -很多常见反馈的安全隐患不在 Express 的安全保障范畴内,需要由应用开发者自行负责处理。 例如未经过滤的用户输入导致的原型污染、静态文件服务配置错误,或第三方依赖项中存在的问题。 +很多常见反馈的安全隐患不在 Express 的安全保障范畴内,需要由应用开发者自行负责处理。例如未经过滤的用户输入导致的原型污染、静态文件服务配置错误,或第三方依赖项中存在的问题。 完整细则请参阅:[Express 威胁模型](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)。 diff --git a/src/content/pages/zh-cn/resources/glossary.mdx b/src/content/pages/zh-cn/resources/glossary.mdx index cbf818e3d7..765707812b 100644 --- a/src/content/pages/zh-cn/resources/glossary.mdx +++ b/src/content/pages/zh-cn/resources/glossary.mdx @@ -7,15 +7,15 @@ import Alert from '@components/primitives/Alert/Alert.astro'; ## 应用程序 -通常指一个或多个为特定目的而设计并执行操作的程序。 在 Express 语境中,指运行在 Node.js 平台上并使用 Express API 的程序。 Might also refer to an [app object](/api#express). +通常指一个或多个为特定目的而设计并执行操作的程序。在 Express 语境中,指运行在 Node.js 平台上并使用 Express API 的程序。 Might also refer to an [app object](/api#express). ## API -应用程序编程接口。 首次使用时请写出缩写的全称。 +应用程序编程接口。首次使用时请写出缩写的全称。 ## Express -一个快速、无约束、极简的 Node.js Web 应用框架。 一般情况下,推荐使用“Express”,而不是“Express.js”,不过后者也是可以接受的。 +一个快速、无约束、极简的 Node.js Web 应用框架。一般情况下,推荐使用“Express”,而不是“Express.js”,不过后者也是可以接受的。 ## libuv @@ -23,9 +23,9 @@ import Alert from '@components/primitives/Alert/Alert.astro'; ## 中间件 -一个在 Express 路由层中、最终请求处理函数之前被调用的函数,它位于原始请求与最终目标路由处理之间。 关于中间件术语的一些细微说明: +一个在 Express 路由层中、最终请求处理函数之前被调用的函数,它位于原始请求与最终目标路由处理之间。关于中间件术语的一些细微说明: -- `var foo = require('middleware')` 被称为“引入”或“使用”一个 Node.js 模块。 随后,语句 `var mw = foo()` 通常会返回该中间件。 +- `var foo = require('middleware')` 被称为“引入”或“使用”一个 Node.js 模块。随后,语句 `var mw = foo()` 通常会返回该中间件。 - `app.use(mw)` 被称为“将中间件添加到全局处理栈中”。 - `app.get('/foo', mw, (req, res) => { /* ... */ })` is called _adding the middleware to the "GET /foo" processing stack_. @@ -45,15 +45,15 @@ import Alert from '@components/primitives/Alert/Alert.astro'; ## request -一次 HTTP 请求。 客户端向服务器发送一条 HTTP 请求消息,服务器随后返回响应。 The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on. +一次 HTTP 请求。客户端向服务器发送一条 HTTP 请求消息,服务器随后返回响应。 The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on. ## response -一个 HTTP 响应。 服务器向客户端返回一条 HTTP 响应消息。 该响应包含请求的完成状态信息,并且可能在消息体中包含所请求的内容。 +一个 HTTP 响应。服务器向客户端返回一条 HTTP 响应消息。该响应包含请求的完成状态信息,并且可能在消息体中包含所请求的内容。 ## route -URL 中用于标识资源的部分。 例如,在 `http://foo.com/products/id` 中,“/products/id” 就是路由。 +URL 中用于标识资源的部分。例如,在 `http://foo.com/products/id` 中,“/products/id” 就是路由。 ## router diff --git a/src/content/pages/zh-cn/resources/index.mdx b/src/content/pages/zh-cn/resources/index.mdx index 25264b7585..175378ad23 100644 --- a/src/content/pages/zh-cn/resources/index.mdx +++ b/src/content/pages/zh-cn/resources/index.mdx @@ -6,7 +6,7 @@ description: 探索Express.js资源,包括社区、贡献准则、词汇、 import Card from '@components/primitives/Card/Card.astro'; import { CardList } from '@components/patterns'; -查找资源,帮助你学习、参与贡献并融入 Express.js 生态系统。 无论你是想参与社区、探索中间件,还是了解核心概念,都能在这里找到所需内容。 +查找资源,帮助你学习、参与贡献并融入 Express.js 生态系统。无论你是想参与社区、探索中间件,还是了解核心概念,都能在这里找到所需内容。
diff --git a/src/content/pages/zh-cn/resources/middleware/body-parser.mdx b/src/content/pages/zh-cn/resources/middleware/body-parser.mdx index 58f8196767..5e53dce90b 100644 --- a/src/content/pages/zh-cn/resources/middleware/body-parser.mdx +++ b/src/content/pages/zh-cn/resources/middleware/body-parser.mdx @@ -17,11 +17,11 @@ Node.js 请求体解析中间件 在处理程序之前,通过中间件解析传入的请求体,解析结果可通过 `req.body` 属性访问。 -**注意** 由于 `req.body` 的结构由用户可控的输入决定,因此该对象中的所有属性和值均不可信,在使用前应进行验证。 例如,`req.body.foo.toString()` 可能会以多种方式报错,例如 `foo` 属性可能不存在或不是字符串,且 `toString` 可能并非函数,而是字符串或其他用户输入。 +**注意** 由于 `req.body` 的结构由用户可控的输入决定,因此该对象中的所有属性和值均不可信,在使用前应进行验证。例如,`req.body.foo.toString()` 可能会以多种方式报错,例如 `foo` 属性可能不存在或不是字符串,且 `toString` 可能并非函数,而是字符串或其他用户输入。 [了解 Node.js 中 HTTP 请求交互的构成](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction) -**此中间件不处理多部分(multipart)请求体**,因其结构复杂且通常体积较大。 对于多部分请求体,你可能需要以下模块: +**此中间件不处理多部分(multipart)请求体**,因其结构复杂且通常体积较大。对于多部分请求体,你可能需要以下模块: - [busboy](https://www.npmjs.com/package/busboy#readme) and [connect-busboy](https://www.npmjs.com/package/connect-busboy#readme) @@ -37,6 +37,10 @@ Node.js 请求体解析中间件 - [Text body parser](#bodyparsertextoptions) - [URL-encoded form body parser](#bodyparserurlencodedoptions) +All parsers support automatic inflation of `gzip`, `br` (brotli), `deflate` +and `zstd` encodings. `zstd` is available in Node.js `^22.15.0` and +`>=23.8.0`. + 你可能感兴趣的其他请求体解析器: - [body](https://www.npmjs.com/package/body#readme) @@ -67,13 +71,14 @@ const raw = require('body-parser/raw'); const text = require('body-parser/text'); ``` -`bodyParser` 对象提供了多种工厂方法来创建中间件。 所有中间件在请求头`Content-Type`与`type`选项匹配时,都会将解析后的请求体存入`req.body`属性。 +`bodyParser` 对象提供了多种工厂方法来创建中间件。所有中间件在请求头`Content-Type`与`type`选项匹配时,都会将解析后的请求体存入`req.body`属性。 该模块抛出的各类错误在[错误章节](#errors)中有相关说明。 ### bodyParser.json([options]) -返回仅解析`json`且仅解析请求头`Content-Type`与`type`选项匹配的请求的中间件。 该解析器可识别请求体的任意Unicode编码,并自动解压`gzip`、`br`(brotli)与`deflate`编码的数据。 +返回仅解析`json`且仅解析请求头`Content-Type`与`type`选项匹配的请求的中间件。 This parser accepts any +Unicode encoding of the body. 中间件执行完成后,解析后的数据会存入请求对象上新增的 `body` 属性(即 `req.body`)。 @@ -87,34 +92,34 @@ const text = require('body-parser/text'); ##### inflate -设为 `true` 时,会解压经过压缩的请求体;设为 `false` 时,则拒绝处理压缩请求体。 默认值为 `true`。 +设为 `true` 时,会解压经过压缩的请求体;设为 `false` 时,则拒绝处理压缩请求体。默认值为 `true`。 ##### limit -控制请求体的最大体积。 若该值为数字,则代表字节数;若为字符串,则交由 [bytes](https://www.npmjs.com/package/bytes) 库解析。 默认值为 `'100kb'`。 +控制请求体的最大体积。若该值为数字,则代表字节数;若为字符串,则交由 [bytes](https://www.npmjs.com/package/bytes) 库解析。默认值为 `'100kb'`。 -> 建议不要设置过大的限制值,尽可能使用默认配置。 允许更大的请求载荷会增加内存占用,因为解码与数据转换需要消耗资源,同时处理更多数据也会延长响应耗时。 此处所说的“过大”指超出默认值的配置,例如5兆及以上的请求载荷就会开始产生上述风险。 使用默认限制值时,不会出现上述问题。 +> 建议不要设置过大的限制值,尽可能使用默认配置。允许更大的请求载荷会增加内存占用,因为解码与数据转换需要消耗资源,同时处理更多数据也会延长响应耗时。此处所说的“过大”指超出默认值的配置,例如5兆及以上的请求载荷就会开始产生上述风险。使用默认限制值时,不会出现上述问题。 ##### reviver -`reviver` 配置项会直接作为第二个参数传入 `JSON.parse`。 你可以在MDN关于JSON.parse的文档中查看该参数的更多信息 +`reviver` 配置项会直接作为第二个参数传入 `JSON.parse`。你可以在MDN关于JSON.parse的文档中查看该参数的更多信息 [MDN JSON.parse文档之reviver参数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#the_reviver_parameter)。 ##### strict -设为 `true` 时,仅接受数组与对象;设为 `false` 时,可接受所有 `JSON.parse` 能够解析的内容。 默认值为 `true`。 +设为 `true` 时,仅接受数组与对象;设为 `false` 时,可接受所有 `JSON.parse` 能够解析的内容。默认值为 `true`。 ##### type -`type` 选项用于指定该中间件所要解析的媒体类型。 该选项可以是字符串、字符串数组或函数。 若不为函数,`type` 选项会直接传入 [type-is](https://www.npmjs.com/package/type-is#readme) 库,它可以是扩展名(如 `json`)、MIME 类型(如 `application/json`)或带通配符的 MIME 类型(如 `*/*`、`*/json`)。 若为函数,则 `type` 选项会以 `fn(req)` 形式调用,当函数返回真值时才会解析该请求。 默认值为 `application/json`。 +`type` 选项用于指定该中间件所要解析的媒体类型。该选项可以是字符串、字符串数组或函数。若不为函数,`type` 选项会直接传入 [type-is](https://www.npmjs.com/package/type-is#readme) 库,它可以是扩展名(如 `json`)、MIME 类型(如 `application/json`)或带通配符的 MIME 类型(如 `*/*`、`*/json`)。若为函数,则 `type` 选项会以 `fn(req)` 形式调用,当函数返回真值时才会解析该请求。默认值为 `application/json`。 ##### verify -如果配置了 `verify` 选项,会以 `verify(req, res, buf, encoding)` 的形式调用,其中 `buf` 是存储原始请求体的 `Buffer`,`encoding` 为请求的编码格式。 可通过抛出错误终止解析流程。 +如果配置了 `verify` 选项,会以 `verify(req, res, buf, encoding)` 的形式调用,其中 `buf` 是存储原始请求体的 `Buffer`,`encoding` 为请求的编码格式。可通过抛出错误终止解析流程。 ### bodyParser.raw([options]) -返回一个中间件,该中间件会将所有请求体解析为 `Buffer`,且仅处理 `Content-Type` 请求头与 `type` 选项匹配的请求。 该解析器支持自动解压 `gzip`、`br`(brotli)与 `deflate` 编码。 +返回一个中间件,该中间件会将所有请求体解析为 `Buffer`,且仅处理 `Content-Type` 请求头与 `type` 选项匹配的请求。 中间件执行完成后,解析后的数据会存入请求对象上新增的 `body` 属性(即 `req.body`)。 This will be a `Buffer` object of the body. @@ -125,28 +130,27 @@ of the body. ##### inflate -设为 `true` 时,会解压经过压缩的请求体;设为 `false` 时,则拒绝处理压缩请求体。 默认值为 `true`。 +设为 `true` 时,会解压经过压缩的请求体;设为 `false` 时,则拒绝处理压缩请求体。默认值为 `true`。 ##### limit -控制请求体的最大体积。 若该值为数字,则代表字节数;若为字符串,则交由 [bytes](https://www.npmjs.com/package/bytes) 库解析。 默认值为 `'100kb'`。 +控制请求体的最大体积。若该值为数字,则代表字节数;若为字符串,则交由 [bytes](https://www.npmjs.com/package/bytes) 库解析。默认值为 `'100kb'`。 -> 建议不要设置过大的限制值,尽可能使用默认配置。 允许更大的请求载荷会增加内存占用,因为解码与数据转换需要消耗资源,同时处理更多数据也会延长响应耗时。 此处所说的“过大”指超出默认值的配置,例如5兆及以上的请求载荷就会开始产生上述风险。 使用默认限制值时,不会出现上述问题。 +> 建议不要设置过大的限制值,尽可能使用默认配置。允许更大的请求载荷会增加内存占用,因为解码与数据转换需要消耗资源,同时处理更多数据也会延长响应耗时。此处所说的“过大”指超出默认值的配置,例如5兆及以上的请求载荷就会开始产生上述风险。使用默认限制值时,不会出现上述问题。 ##### type -`type` 选项用于指定该中间件所要解析的媒体类型。 该选项可以是字符串、字符串数组或函数。 -若不为函数,`type` 选项会直接传入 [type-is](https://www.npmjs.com/package/type-is#readme) 库,它可以是扩展名(如 `bin`)、MIME 类型(如 `application/octet-stream`)或带通配符的 MIME 类型(如 `*/*`、`application/*`)。 若为函数,则 `type` 选项会以 `fn(req)` 形式调用,函数返回真值时才会解析该请求。 默认值为 `application/octet-stream`。 +`type` 选项用于指定该中间件所要解析的媒体类型。该选项可以是字符串、字符串数组或函数。若不为函数,`type` 选项会直接传入 [type-is](https://www.npmjs.com/package/type-is#readme) 库,它可以是扩展名(如 `bin`)、MIME 类型(如 `application/octet-stream`)或带通配符的 MIME 类型(如 `*/*`、`application/*`)。若为函数,则 `type` 选项会以 `fn(req)` 形式调用,函数返回真值时才会解析该请求。默认值为 `application/octet-stream`。 ##### verify -如果配置了 `verify` 选项,会以 `verify(req, res, buf, encoding)` 的形式调用,其中 `buf` 是存储原始请求体的 `Buffer`,`encoding` 为请求的编码格式。 可通过抛出错误终止解析流程。 +如果配置了 `verify` 选项,会以 `verify(req, res, buf, encoding)` 的形式调用,其中 `buf` 是存储原始请求体的 `Buffer`,`encoding` 为请求的编码格式。可通过抛出错误终止解析流程。 ### bodyParser.text([options]) -返回一个中间件,该中间件会将所有请求体解析为字符串,且仅处理 `Content-Type` 请求头与 `type` 选项匹配的请求。 该解析器支持自动解压 `gzip`、`br`(brotli)与 `deflate` 编码。 +返回一个中间件,该中间件会将所有请求体解析为字符串,且仅处理 `Content-Type` 请求头与 `type` 选项匹配的请求。 -中间件执行完成后,解析得到的字符串数据会作为新的 `body` 属性挂载到请求对象上(即 `req.body`)。 该值为请求体对应的字符串。 +中间件执行完成后,解析得到的字符串数据会作为新的 `body` 属性挂载到请求对象上(即 `req.body`)。该值为请求体对应的字符串。 #### Options @@ -158,27 +162,28 @@ of the body. ##### inflate -设为 `true` 时,会解压经过压缩的请求体;设为 `false` 时,则拒绝处理压缩请求体。 默认值为 `true`。 +设为 `true` 时,会解压经过压缩的请求体;设为 `false` 时,则拒绝处理压缩请求体。默认值为 `true`。 ##### limit -控制请求体的最大体积。 若该值为数字,则代表字节数;若为字符串,则交由 [bytes](https://www.npmjs.com/package/bytes) 库解析。 默认值为 `'100kb'`。 +控制请求体的最大体积。若该值为数字,则代表字节数;若为字符串,则交由 [bytes](https://www.npmjs.com/package/bytes) 库解析。默认值为 `'100kb'`。 -> 建议不要设置过大的限制值,尽可能使用默认配置。 允许更大的请求载荷会增加内存占用,因为解码与数据转换需要消耗资源,同时处理更多数据也会延长响应耗时。 此处所说的“过大”指超出默认值的配置,例如5兆及以上的请求载荷就会开始产生上述风险。 使用默认限制值时,不会出现上述问题。 +> 建议不要设置过大的限制值,尽可能使用默认配置。允许更大的请求载荷会增加内存占用,因为解码与数据转换需要消耗资源,同时处理更多数据也会延长响应耗时。此处所说的“过大”指超出默认值的配置,例如5兆及以上的请求载荷就会开始产生上述风险。使用默认限制值时,不会出现上述问题。 ##### type -`type` 选项用于指定该中间件所要解析的媒体类型。 该选项可以是字符串、字符串数组或函数。 若不为函数,`type` 选项会直接传入 [type-is](https://www.npmjs.com/package/type-is#readme) 库,它可以是扩展名(如 `txt`)、MIME 类型(如 `text/plain`)或带通配符的 MIME 类型(如 `*/*`、`text/*`)。 若为函数,则 `type` 选项会以 `fn(req)` 形式调用,当函数返回真值时才会解析该请求。 默认值为 `text/plain`。 +`type` 选项用于指定该中间件所要解析的媒体类型。该选项可以是字符串、字符串数组或函数。若不为函数,`type` 选项会直接传入 [type-is](https://www.npmjs.com/package/type-is#readme) 库,它可以是扩展名(如 `txt`)、MIME 类型(如 `text/plain`)或带通配符的 MIME 类型(如 `*/*`、`text/*`)。若为函数,则 `type` 选项会以 `fn(req)` 形式调用,当函数返回真值时才会解析该请求。默认值为 `text/plain`。 ##### verify -如果配置了 `verify` 选项,会以 `verify(req, res, buf, encoding)` 的形式调用,其中 `buf` 是存储原始请求体的 `Buffer`,`encoding` 为请求的编码格式。 可通过抛出错误终止解析流程。 +如果配置了 `verify` 选项,会以 `verify(req, res, buf, encoding)` 的形式调用,其中 `buf` 是存储原始请求体的 `Buffer`,`encoding` 为请求的编码格式。可通过抛出错误终止解析流程。 ### bodyParser.urlencoded([options]) -返回一个中间件,该中间件仅解析 `urlencoded` 格式请求体,且只处理 `Content-Type` 请求头与 `type` 选项匹配的请求。 该解析器仅支持 UTF-8 和 ISO-8859-1 编码的请求体,同时可自动解压 `gzip`、`br`(brotli)与 `deflate` 编码数据。 +返回一个中间件,该中间件仅解析 `urlencoded` 格式请求体,且只处理 `Content-Type` 请求头与 `type` 选项匹配的请求。 This +parser accepts only UTF-8 and ISO-8859-1 encodings of the body. -中间件执行完成后,解析后的数据会存入请求对象上新增的 `body` 属性(即 `req.body`)。 该对象将包含键值对,值可以为字符串或数组(当`extended`为`false`时),或任意类型(当`extended`为`true`时)。 +中间件执行完成后,解析后的数据会存入请求对象上新增的 `body` 属性(即 `req.body`)。该对象将包含键值对,值可以为字符串或数组(当`extended`为`false`时),或任意类型(当`extended`为`true`时)。 #### Options @@ -186,51 +191,51 @@ of the body. ##### extended -`extended` 语法支持将复杂对象与数组编码为URL编码格式,让URL编码数据拥有类似JSON的使用体验。 如需了解更多信息,请[查看 qs 库](https://www.npmjs.com/package/qs#readme)。 +`extended` 语法支持将复杂对象与数组编码为URL编码格式,让URL编码数据拥有类似JSON的使用体验。如需了解更多信息,请[查看 qs 库](https://www.npmjs.com/package/qs#readme)。 默认值为`false`。 ##### inflate -设为 `true` 时,会解压经过压缩的请求体;设为 `false` 时,则拒绝处理压缩请求体。 默认值为 `true`。 +设为 `true` 时,会解压经过压缩的请求体;设为 `false` 时,则拒绝处理压缩请求体。默认值为 `true`。 ##### limit -控制请求体的最大体积。 若该值为数字,则代表字节数;若为字符串,则交由 [bytes](https://www.npmjs.com/package/bytes) 库解析。 默认值为 `'100kb'`。 +控制请求体的最大体积。若该值为数字,则代表字节数;若为字符串,则交由 [bytes](https://www.npmjs.com/package/bytes) 库解析。默认值为 `'100kb'`。 -> 建议不要设置过大的限制值,尽可能使用默认配置。 允许更大的请求载荷会增加内存占用,因为解码与数据转换需要消耗资源,同时处理更多数据也会延长响应耗时。 此处所说的“过大”指超出默认值的配置,例如5兆及以上的请求载荷就会开始产生上述风险。 使用默认限制值时,不会出现上述问题。 +> 建议不要设置过大的限制值,尽可能使用默认配置。允许更大的请求载荷会增加内存占用,因为解码与数据转换需要消耗资源,同时处理更多数据也会延长响应耗时。此处所说的“过大”指超出默认值的配置,例如5兆及以上的请求载荷就会开始产生上述风险。使用默认限制值时,不会出现上述问题。 ##### parameterLimit -`parameterLimit` 选项用于控制 URL 编码数据中允许携带的最大参数数量。 如果请求包含的参数数量超过该设定值,将会向客户端返回 413 状态码。 默认值为 `1000`。 +`parameterLimit` 选项用于控制 URL 编码数据中允许携带的最大参数数量。如果请求包含的参数数量超过该设定值,将会向客户端返回 413 状态码。默认值为 `1000`。 ##### type -`type` 选项用于指定该中间件所要解析的媒体类型。 该选项可以是字符串、字符串数组或函数。 若`type`选项不是函数,则会直接传递给[type-is](https://www.npmjs.com/package/type-is#readme)库,该值可以是文件扩展名(如`urlencoded`)、MIME类型(如`application/x-www-form-urlencoded`)或带通配符的MIME类型(如`*/x-www-form-urlencoded`)。 如果`type`选项为函数,则以`fn(req)`形式调用该函数;若返回真值,则解析本次请求。 默认值为 `application/x-www-form-urlencoded`。 +`type` 选项用于指定该中间件所要解析的媒体类型。该选项可以是字符串、字符串数组或函数。若`type`选项不是函数,则会直接传递给[type-is](https://www.npmjs.com/package/type-is#readme)库,该值可以是文件扩展名(如`urlencoded`)、MIME类型(如`application/x-www-form-urlencoded`)或带通配符的MIME类型(如`*/x-www-form-urlencoded`)。如果`type`选项为函数,则以`fn(req)`形式调用该函数;若返回真值,则解析本次请求。默认值为 `application/x-www-form-urlencoded`。 ##### verify -如果配置了 `verify` 选项,会以 `verify(req, res, buf, encoding)` 的形式调用,其中 `buf` 是存储原始请求体的 `Buffer`,`encoding` 为请求的编码格式。 可通过抛出错误终止解析流程。 +如果配置了 `verify` 选项,会以 `verify(req, res, buf, encoding)` 的形式调用,其中 `buf` 是存储原始请求体的 `Buffer`,`encoding` 为请求的编码格式。可通过抛出错误终止解析流程。 ##### 默认字符集 -当请求头 Content-Type 未指定字符集时,用于解析数据的默认字符集。 必须为 `utf-8` 或 `iso-8859-1` 二者之一。 Defaults to `utf-8`. +当请求头 Content-Type 未指定字符集时,用于解析数据的默认字符集。必须为 `utf-8` 或 `iso-8859-1` 二者之一。 Defaults to `utf-8`. ##### charsetSentinel -是否允许 `utf8` 参数的值优先作为字符集选择依据。 要求表单包含一个名为 `utf8`、值为 `✓` 的参数。 默认值为`false`。 +是否允许 `utf8` 参数的值优先作为字符集选择依据。要求表单包含一个名为 `utf8`、值为 `✓` 的参数。默认值为`false`。 ##### interpretNumericEntities -解析 iso-8859-1 格式表单时,是否解码 `☺` 这类数字实体字符。 默认值为`false`。 +解析 iso-8859-1 格式表单时,是否解码 `☺` 这类数字实体字符。默认值为`false`。 ##### depth -当 `extended` 为 `true` 时,`depth` 选项用于配置 `qs` 库解析对象的最大嵌套深度。 该配置可限制解析出的键值数量,有助于防范特定类型的恶意攻击。 默认值为 `32`。 建议将该值设置得尽可能小。 +当 `extended` 为 `true` 时,`depth` 选项用于配置 `qs` 库解析对象的最大嵌套深度。该配置可限制解析出的键值数量,有助于防范特定类型的恶意攻击。默认值为 `32`。建议将该值设置得尽可能小。 ## Errors -本模块提供的中间件会借助[`http-errors` 模块](https://www.npmjs.com/package/http-errors)生成错误对象。 错误对象通常包含以下属性: +本模块提供的中间件会借助[`http-errors` 模块](https://www.npmjs.com/package/http-errors)生成错误对象。错误对象通常包含以下属性: `status`/`statusCode`:推荐使用的 HTTP 响应状态码; `expose`:控制是否向客户端展示 `message` 信息; `type`:用于区分错误类型,无需匹配消息文本; @@ -250,7 +255,8 @@ the entity value that failed parsing. ### 实体验证失败 -当请求实体无法通过配置的 `verify` 选项校验时,会触发该错误。 `status` 属性值为 `403`,`type` 属性值为 `'entity.verify.failed'`,`body` 属性存放校验未通过的请求实体内容。 +This error will occur when the request contained an entity that could not be +verified by the defined `verify` option. `status` 属性值为 `403`,`type` 属性值为 `'entity.verify.failed'`,`body` 属性存放校验未通过的请求实体内容。 ### request aborted @@ -262,15 +268,15 @@ the entity value that failed parsing. ### 请求体实际大小与Content Length不匹配 -当请求实际数据长度与 `Content-Length` 请求头标明的长度不一致时,会触发该错误。 该错误通常由格式异常的请求引发,常见场景是 `Content-Length` 请求头按照字符数而非字节数计算得出。 `status` 属性值为 `400`,`type` 属性值为 `'request.size.invalid'`。 +当请求实际数据长度与 `Content-Length` 请求头标明的长度不一致时,会触发该错误。该错误通常由格式异常的请求引发,常见场景是 `Content-Length` 请求头按照字符数而非字节数计算得出。 `status` 属性值为 `400`,`type` 属性值为 `'request.size.invalid'`。 ### 不应设置流编码 -若在当前中间件执行前,有代码调用过 `req.setEncoding` 方法,则会触发该错误。 该模块仅直接处理原始字节流,使用本模块时不可调用 `req.setEncoding` 方法。 `status` 属性值为 `500`,`type` 属性值为 `'stream.encoding.set'`。 +若在当前中间件执行前,有代码调用过 `req.setEncoding` 方法,则会触发该错误。该模块仅直接处理原始字节流,使用本模块时不可调用 `req.setEncoding` 方法。 `status` 属性值为 `500`,`type` 属性值为 `'stream.encoding.set'`。 ### stream is not readable -当中间件尝试读取请求流,但该请求流已不可读时,会抛出该错误。 这种情况通常是:除了本模块中间件之外,已有其他代码提前读取过请求体,但当前中间件又被配置去读取同一个请求流。 `status` 属性值为 `500`,`type` 属性值为 `'stream.not.readable'`。 +当中间件尝试读取请求流,但该请求流已不可读时,会抛出该错误。这种情况通常是:除了本模块中间件之外,已有其他代码提前读取过请求体,但当前中间件又被配置去读取同一个请求流。 `status` 属性值为 `500`,`type` 属性值为 `'stream.not.readable'`。 ### 参数太多了 @@ -278,22 +284,21 @@ the entity value that failed parsing. ### 不支持的字符编码“BOGUS” -当请求的 `Content-Type` 请求头携带 charset 参数,但 iconv-lite 模块或当前解析器不支持该字符集时,会抛出此错误。 错误信息与 `charset` 属性中均会携带对应的字符集名称。 `status` 属性值为 `415`,`type` 属性值为 `'charset.unsupported'`,`charset` 属性存储不被支持的字符集名称。 +当请求的 `Content-Type` 请求头携带 charset 参数,但 iconv-lite 模块或当前解析器不支持该字符集时,会抛出此错误。错误信息与 `charset` 属性中均会携带对应的字符集名称。 `status` 属性值为 `415`,`type` 属性值为 `'charset.unsupported'`,`charset` 属性存储不被支持的字符集名称。 ### 不支持的内容编码格式“bogus” -当请求头 `Content-Encoding` 中携带了不被支持的编码格式时,会触发该错误。 错误信息与 `encoding` 属性都会包含对应的编码标识。 `status` 属性值为 `415`,`type` 属性值为 `'encoding.unsupported'`,`encoding` 属性存储不被支持的编码格式。 +当请求头 `Content-Encoding` 中携带了不被支持的编码格式时,会触发该错误。错误信息与 `encoding` 属性都会包含对应的编码标识。 `status` 属性值为 `415`,`type` 属性值为 `'encoding.unsupported'`,`encoding` 属性存储不被支持的编码格式。 ### 输入内容超出解析深度限制 -当使用 `bodyParser.urlencoded` 并将 `extended` 配置为 `true` 时,若传入参数嵌套层级超过 `depth` 配置上限,就会触发该错误。 `status` 属性值为 `400`。 建议检查 `depth` 配置项,评估是否需要调大该数值。 当 `depth` 配置项设为默认值 32 时,不会抛出该错误。 +当使用 `bodyParser.urlencoded` 并将 `extended` 配置为 `true` 时,若传入参数嵌套层级超过 `depth` 配置上限,就会触发该错误。 `status` 属性值为 `400`。建议检查 `depth` 配置项,评估是否需要调大该数值。当 `depth` 配置项设为默认值 32 时,不会抛出该错误。 ## Examples ### Express/Connect 顶层通用方法 -此示例演示将通用 JSON 和 URL 编码解析器注册为顶层中间件,它会解析所有入站请求的请求体。 -这是最简配置方案。 +此示例演示将通用 JSON 和 URL 编码解析器注册为顶层中间件,它会解析所有入站请求的请求体。这是最简配置方案。 ```js const express = require('express'); @@ -316,7 +321,7 @@ app.use(function (req, res) { ### Express 路由专属 -该示例演示仅为需要的路由单独配置请求体解析器。 通常来说,这是在 Express 中使用 body-parser 最推荐的方式。 +该示例演示仅为需要的路由单独配置请求体解析器。通常来说,这是在 Express 中使用 body-parser 最推荐的方式。 ```js const express = require('express'); diff --git a/src/content/pages/zh-cn/resources/middleware/compression.mdx b/src/content/pages/zh-cn/resources/middleware/compression.mdx index 162d32c2c2..be10551790 100644 --- a/src/content/pages/zh-cn/resources/middleware/compression.mdx +++ b/src/content/pages/zh-cn/resources/middleware/compression.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -21,13 +21,13 @@ The following compression codings are supported: - gzip - br (brotli) -**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0. +**Note** Brotli is available in all currently supported Node.js LTS versions (v18+). ## Install This is a [Node.js](https://nodejs.org/en/) module available through the [npm registry](https://www.npmjs.com/). Installation is done using the -[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): +[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally): @@ -304,7 +304,7 @@ The Express.js project welcomes all constructive contributions. Contributions ta from code for bug fixes and enhancements, to additions and fixes to documentation, additional tests, triaging incoming pull requests and issues, and more! -See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing. +See the [Contributing Guide](https://github.com/expressjs/.github/blob/HEAD/CONTRIBUTING.md) for more technical details on contributing. ## License diff --git a/src/content/pages/zh-cn/resources/middleware/cookie-parser.mdx b/src/content/pages/zh-cn/resources/middleware/cookie-parser.mdx index c28946c0b0..ced9ad6727 100644 --- a/src/content/pages/zh-cn/resources/middleware/cookie-parser.mdx +++ b/src/content/pages/zh-cn/resources/middleware/cookie-parser.mdx @@ -13,7 +13,7 @@ import PackageManagerCommand from '@components/patterns/PackageManagerCommand/Pa npm="https://www.npmjs.com/package/cookie-parser" /> -解析 `Cookie` 请求头,并以 Cookie 名称为键生成对象挂载至 `req.cookies`。 你也可传入 `secret` 字符串开启签名 Cookie 支持,该参数会赋值给 `req.secret`,供其他中间件使用。 +解析 `Cookie` 请求头,并以 Cookie 名称为键生成对象挂载至 `req.cookies`。你也可传入 `secret` 字符串开启签名 Cookie 支持,该参数会赋值给 `req.secret`,供其他中间件使用。 ## 安装 @@ -37,36 +37,35 @@ var cookieParser = require('cookie-parser'); 使用传入的 `secret` 与 `options` 创建全新的 Cookie 解析中间件函数。 -- `secret`:用于签名 Cookie 的字符串或数组。 该参数为可选参数,若未指定,则不会解析签名 Cookie。 若传入字符串,则将其作为密钥。 若传入数组,会按顺序使用数组内每个密钥尝试解密签名 Cookie。 -- `options`:作为第二个参数传入 `cookie.parse` 的配置对象。 更多详情请查看 [cookie](https://www.npmjs.org/package/cookie)。 +- `secret`:用于签名 Cookie 的字符串或数组。该参数为可选参数,若未指定,则不会解析签名 Cookie。若传入字符串,则将其作为密钥。若传入数组,会按顺序使用数组内每个密钥尝试解密签名 Cookie。 +- `options`:作为第二个参数传入 `cookie.parse` 的配置对象。更多详情请查看 [cookie](https://www.npmjs.org/package/cookie)。 - `decode`:用于解码 Cookie 值的函数 -该中间件会解析请求头中的`Cookie`,并将 Cookie 数据挂载为`req.cookies`属性;若传入了`secret`密钥,则同时挂载为`req.signedCookies`属性。 这些属性是键值对,代表 Cookie 名称与对应 Cookie 值。 +该中间件会解析请求头中的`Cookie`,并将 Cookie 数据挂载为`req.cookies`属性;若传入了`secret`密钥,则同时挂载为`req.signedCookies`属性。这些属性是键值对,代表 Cookie 名称与对应 Cookie 值。 -当配置`secret`密钥时,该模块会对所有签名Cookie值进行解签与校验,并将对应的键值对从`req.cookies`转移至`req.signedCookies`中。 -签名 Cookie 是值以`s:`作为前缀的 Cookie。 签名校验失败的签名 Cookie,其值会为`false`,而非被篡改后的内容。 +当配置`secret`密钥时,该模块会对所有签名Cookie值进行解签与校验,并将对应的键值对从`req.cookies`转移至`req.signedCookies`中。签名 Cookie 是值以`s:`作为前缀的 Cookie。签名校验失败的签名 Cookie,其值会为`false`,而非被篡改后的内容。 -此外,该模块支持特殊的“JSON Cookie”。 这类 Cookie 的值以 `j:` 作为前缀。 当识别到这类值时,会将其经`JSON.parse`解析后的结果对外暴露。 若解析失败,则保留原始值。 +此外,该模块支持特殊的“JSON Cookie”。这类 Cookie 的值以 `j:` 作为前缀。当识别到这类值时,会将其经`JSON.parse`解析后的结果对外暴露。若解析失败,则保留原始值。 ### cookieParser.JSONCookie(str) -将 Cookie 值解析为 JSON Cookie。 如果是 JSON Cookie,将返回解析后的 JSON 值;否则返回传入的原始值。 +将 Cookie 值解析为 JSON Cookie。如果是 JSON Cookie,将返回解析后的 JSON 值;否则返回传入的原始值。 ### cookieParser.JSONCookies(cookies) -传入一个对象后,该方法会遍历对象所有键,并对每个值调用`JSONCookie`,用解析后的值替换原有值。 该方法返回传入的原对象。 +传入一个对象后,该方法会遍历对象所有键,并对每个值调用`JSONCookie`,用解析后的值替换原有值。该方法返回传入的原对象。 ### cookieParser.signedCookie(str, secret) -将 Cookie 值解析为签名 Cookie。 若为签名 Cookie 且签名校验通过,则返回解析后的未签名值。 若该值未经过签名,则返回原始值。 若该值已签名但签名校验不通过,则返回`false`。 +将 Cookie 值解析为签名 Cookie。若为签名 Cookie 且签名校验通过,则返回解析后的未签名值。若该值未经过签名,则返回原始值。若该值已签名但签名校验不通过,则返回`false`。 -`secret` 参数可以为字符串或数组。 若传入字符串,则将其用作密钥。 若传入数组,则会按顺序使用数组内每一个密钥尝试对Cookie解签。 +`secret` 参数可以为字符串或数组。若传入字符串,则将其用作密钥。若传入数组,则会按顺序使用数组内每一个密钥尝试对Cookie解签。 ### cookieParser.signedCookies(cookies, secret) -传入一个对象时,该方法会遍历所有键,并检测每个值是否为签名 Cookie。 如果是签名 Cookie 且签名校验有效,则从原对象中删除该键,并将其添加到返回的新对象中。 +传入一个对象时,该方法会遍历所有键,并检测每个值是否为签名 Cookie。如果是签名 Cookie 且签名校验有效,则从原对象中删除该键,并将其添加到返回的新对象中。 -`secret` 参数可以为字符串或数组。 若传入字符串,则将其用作密钥。 若传入数组,则会按顺序使用数组内每一个密钥尝试对Cookie解签。 +`secret` 参数可以为字符串或数组。若传入字符串,则将其用作密钥。若传入数组,则会按顺序使用数组内每一个密钥尝试对Cookie解签。 ## 示例 diff --git a/src/content/pages/zh-cn/resources/middleware/cookie-session.mdx b/src/content/pages/zh-cn/resources/middleware/cookie-session.mdx index d9db6b0052..d250082180 100644 --- a/src/content/pages/zh-cn/resources/middleware/cookie-session.mdx +++ b/src/content/pages/zh-cn/resources/middleware/cookie-session.mdx @@ -124,7 +124,7 @@ The options can also contain any of the following (for the full list, see - `partitioned`: a boolean indicating whether to partition the cookie in Chrome for the [CHIPS Update](https://developers.google.com/privacy-sandbox/3pcd/chips) (`false` by default). If this is true, Cookies from embedded sites will be partitioned and only readable from the same top level site from which it was created. - `priority`: a string indicating the cookie priority. This can be set to `'low'`, `'medium'`, or `'high'`. - `sameSite`: a boolean or string indicating whether the cookie is a "same site" cookie (`false` by default). This can be set to `'strict'`, `'lax'`, `'none'`, or `true` (which maps to `'strict'`). -- `secure`: a boolean indicating whether the cookie is only to be sent over HTTPS (`false` by default for HTTP, `true` by default for HTTPS). If this is set to `true` and Node.js is not directly over a TLS connection, be sure to read how to [setup Express behind proxies](/guide/behind-proxies) or the cookie may not ever set correctly. +- `secure`: a boolean indicating whether the cookie is only to be sent over HTTPS (`false` by default for HTTP, `true` by default for HTTPS). If this is set to `true` and Node.js is not directly over a TLS connection, be sure to read how to [setup Express behind proxies](/guide/behind-proxies/) or the cookie may not ever set correctly. - `httpOnly`: a boolean indicating whether the cookie is only to be sent over HTTP(S), and not made available to client JavaScript (`true` by default). - `signed`: a boolean indicating whether the cookie is to be signed (`true` by default). - `overwrite`: a boolean indicating whether to overwrite previously set cookies of the same name (`true` by default). diff --git a/src/content/pages/zh-cn/resources/middleware/index.mdx b/src/content/pages/zh-cn/resources/middleware/index.mdx index df34d1fcb6..9b6c83231b 100644 --- a/src/content/pages/zh-cn/resources/middleware/index.mdx +++ b/src/content/pages/zh-cn/resources/middleware/index.mdx @@ -32,7 +32,7 @@ The Express middleware modules listed here are maintained by the These are some additional popular middleware modules. - 这些信息指的是第三方站点、产品或模块,它们不是由Expressjs团队维护的。 此处的罗列并不代表 Express + 这些信息指的是第三方站点、产品或模块,它们不是由Expressjs团队维护的。此处的罗列并不代表 Express 项目团队的认可或推荐。 diff --git a/src/content/pages/zh-cn/resources/middleware/morgan.mdx b/src/content/pages/zh-cn/resources/middleware/morgan.mdx index 6a31bcc46f..a3638ef075 100644 --- a/src/content/pages/zh-cn/resources/middleware/morgan.mdx +++ b/src/content/pages/zh-cn/resources/middleware/morgan.mdx @@ -8,14 +8,14 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; HTTP request logger middleware for node.js -> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. +> Named after [Dexter](https://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. ## 安装 @@ -35,6 +35,16 @@ This is a [Node.js](https://nodejs.org/en/) module available through the ## API +For ES Modules: + +{/* eslint-disable no-unused-vars */} + +```js +import morgan from 'morgan'; +``` + +For CommonJS: + {/* eslint-disable no-unused-vars */} ```js @@ -78,10 +88,12 @@ morgan(function (tokens, req, res) { tokens.method(req, res), tokens.url(req, res), tokens.status(req, res), - tokens.res(req, res, 'content-length'), '-', - tokens['response-time'](https://github.com/expressjs/morgan/blob/HEAD/req, res), 'ms' - ].join(' ') -}) + tokens.res(req, res, 'content-length'), + '-', + tokens['response-time'](req, res), + 'ms', + ].join(' '); +}); ``` #### Options @@ -90,7 +102,7 @@ Morgan accepts these properties in the options object. ##### immediate -Write log line on request instead of response. This means that a requests will +Write log line on request instead of response. This means that requests will be logged even if the server crashes, _but data from the response (like the response code, content length, etc.) cannot be logged_. @@ -114,6 +126,33 @@ morgan('combined', { Output stream for writing log lines, defaults to `process.stdout`. +If the stream is in object mode (`stream.writableObjectMode` is `true`) and the +format function returns an object, the object is written to the stream as-is, +without a trailing newline. This allows passing structured log entries to +loggers that accept objects: + +{/* eslint-disable no-undef */} + +```js +morgan( + function (tokens, req, res) { + return { + method: tokens.method(req, res), + url: tokens.url(req, res), + status: Number(tokens.status(req, res)), + }; + }, + { + stream: { + writableObjectMode: true, + write: function (entry) { + // entry is the object returned by the format function + }, + }, + } +); +``` + #### Predefined Formats There are various pre-defined formats provided: @@ -151,6 +190,11 @@ for information codes. GET /dev 200 0.224 ms - 2 ``` +Coloring is disabled when the [`NO_COLOR`](https://no-color.org) environment +variable is set to any non-empty value, in which case the output above is +written without any escape sequences. The variable is read once, when `morgan` +is first required. + ##### short Shorter than default, also including response time. @@ -192,7 +236,7 @@ token definition. The token function is expected to be called with the arguments `req` and `res`, representing the HTTP request and HTTP response. Additionally, the token can accept further arguments of -it's choosing to customize behavior. +its choosing to customize behavior. ##### :date[format] @@ -218,7 +262,7 @@ The process ID of the Node.js process handling the request. ##### -The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer. +The Referrer header of the request. This will use the standard mis-spelled Referer header if it exists, otherwise Referrer. ##### :remote-addr @@ -264,7 +308,7 @@ include on the number, defaulting to `3`, which provides microsecond precision. ##### -The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`. +The URL of the request. This will use `req.originalUrl` if it exists, otherwise `req.url`. ##### :user-agent @@ -274,12 +318,12 @@ The contents of the User-Agent header of the request. Compile a format string into a `format` function for use by `morgan`. A format string is a string that represents a single log line and can utilize token syntax. -Tokens are references by `:token-name`. If tokens accept arguments, they can +Tokens are referenced by `:token-name`. If tokens accept arguments, they can be passed using `[]`, for example: `:token-name[pretty]` would pass the string `'pretty'` as an argument to the token `token-name`. The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and -`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and +`res`, where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res` is the HTTP response. The function will return a string that will be the log line, or `undefined` / `null` to skip logging. @@ -290,7 +334,7 @@ advanced uses, this compile function is directly available. ### express/connect -Sample app that will log all request in the Apache combined format to STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var express = require('express'); @@ -307,7 +351,7 @@ app.get('/', function (req, res) { ### vanilla http server -Sample app that will log all request in the Apache combined format to STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var finalhandler = require('finalhandler'); @@ -431,7 +475,7 @@ Sample app that will use custom token formats. This adds an ID to all requests a ```js var express = require('express'); var morgan = require('morgan'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); morgan.token('id', function getId(req) { return req.id; diff --git a/src/content/pages/zh-cn/resources/middleware/multer.mdx b/src/content/pages/zh-cn/resources/middleware/multer.mdx index 581e2f5822..ad9365d875 100644 --- a/src/content/pages/zh-cn/resources/middleware/multer.mdx +++ b/src/content/pages/zh-cn/resources/middleware/multer.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -18,23 +18,6 @@ on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency. **NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`). -## Translations - -This README is also available in other languages: - -| | | -| ------------------------------------------------------------------------------ | --------------- | -| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic | -| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese | -| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French | -| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean | -| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) | -| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian | -| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish | -| [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) | Turkish | - ## 安装 @@ -130,23 +113,26 @@ app.post('/stats', upload.single('uploaded_file'), function (req, res) { }); ``` +Complete client-side and server-side examples (browser `FormData` uploads of a +blob and of an image) are in the [`examples/`](https://github.com/expressjs/multer/blob/HEAD/examples/) folder. + ## API ### File information Each file contains the following information: -| Key | 描述 | Note | -| -------------- | --------------------------------------------- | --------------- | -| `fieldname` | Field name specified in the form | | -| `originalname` | Name of the file on the user's computer | | -| `encoding` | Encoding type of the file | | -| `mimetype` | Mime type of the file | | -| `size` | Size of the file in bytes | | -| `destination` | The folder to which the file has been saved | `DiskStorage` | -| `filename` | The name of the file within the `destination` | `DiskStorage` | -| `path` | The full path to the uploaded file | `DiskStorage` | -| `buffer` | A `Buffer` of the entire file | `MemoryStorage` | +| Key | 描述 | Note | +| -------------- | ----------------------------------------------------------------------------------- | --------------- | +| `fieldname` | Field name specified in the form | | +| `originalname` | Name of the file on the user's computer, or the full path when `preservePath: true` | | +| `encoding` | Encoding type of the file | | +| `mimetype` | Mime type of the file | | +| `size` | Size of the file in bytes | | +| `destination` | The folder to which the file has been saved | `DiskStorage` | +| `filename` | The name of the file within the `destination` | `DiskStorage` | +| `path` | The full path to the uploaded file | `DiskStorage` | +| `buffer` | A `Buffer` of the entire file | `MemoryStorage` | ### `multer(opts)` @@ -161,11 +147,15 @@ The following are the options that can be passed to Multer. | Key | 描述 | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `defCharset` | Default character set to use for text field values that do not declare one. Default: `'utf8'` | +| `defParamCharset` | Default character set to use for values of part header parameters (e.g. filename) that are not extended parameters (that contain an explicit charset). Default: `'latin1'` | | `dest` or `storage` | Where to store the files | | `fileFilter` | Function to control which files are accepted | +| `fileHwm` | `highWaterMark` of each file stream (`file.stream`). Default: busboy's default | +| `highWaterMark` | `highWaterMark` of the multipart parser stream. Default: busboy's default | | `limits` | Limits of the uploaded data | -| `preservePath` | Keep the full path of files instead of just the base name | -| `defParamCharset` | Default character set to use for values of part header parameters (e.g. filename) that are not extended parameters (that contain an explicit charset). Default: `'latin1'` | +| `preservePath` | Keep the full client-supplied path in `file.originalname` instead of just the base name | +| `streamHandler` | Function that feeds the request body to busboy; defaults to `req.pipe(busboy)` | In an average web app, only `dest` might be required, and configured as shown in the following example. @@ -174,6 +164,14 @@ the following example. const upload = multer({ dest: 'uploads/' }); ``` +When `preservePath` is enabled, Multer passes the incoming filename through with +any path segments provided by the client. This is exposed as `file.originalname`; +it does not change the destination folder, create directories, or sanitize the +path for you. `file.originalname` is always client-supplied and should be treated +as untrusted; with `preservePath` it additionally contains the path segments the +client sent. Normalize or validate it before using it in a custom `filename` or +storage engine. + If you want more control over your uploads, you'll want to use the `storage` option instead of `dest`. Multer ships with storage engines `DiskStorage` and `MemoryStorage`; More engines are available from third parties. @@ -189,6 +187,9 @@ Accept an array of files, all with the name `fieldname`. Optionally error out if more than `maxCount` files are uploaded. The array of files will be stored in `req.files`. +Files skipped by `fileFilter` do not count towards `maxCount`. Use +`limits.files` to bound how many files are read from a request. + #### `.fields(fields)` Accept a mix of files, specified by `fields`. An object with arrays of files @@ -207,11 +208,11 @@ Example: #### `.none()` Accept only text fields. If any file upload is made, error with code -"LIMIT_UNEXPECTED_FILE" will be issued. +`LIMIT_UNEXPECTED_FILE` will be issued. #### `.any()` -Accepts all files that comes over the wire. An array of files will be stored in +Accepts all files that come over the wire. An array of files will be stored in `req.files`. **WARNING:** Make sure that you always handle the files that a user uploads. @@ -226,21 +227,26 @@ where you are handling the uploaded files. The disk storage engine gives you full control on storing files to disk. ```javascript +const crypto = require('crypto'); + const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/tmp/my-uploads'); }, filename: function (req, file, cb) { - const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); - cb(null, file.fieldname + '-' + uniqueSuffix); + crypto.randomBytes(16, function (err, raw) { + if (err) return cb(err); + cb(null, file.fieldname + '-' + raw.toString('hex')); + }); }, }); const upload = multer({ storage: storage }); ``` -There are two options available, `destination` and `filename`. They are both -functions that determine where the file should be stored. +There are three options available: `destination`, `filename` and `flush`. All of +them except `flush` are functions that determine where the file should be +stored. `destination` is used to determine within which folder the uploaded files should be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no @@ -268,6 +274,14 @@ For understanding the calling convention used in the callback (needing to pass null as the first param), refer to [Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors) +`flush` is an optional boolean. When set to `true`, the file data is flushed to +disk with an `fsync` call before the upload handler runs, which prevents data +loss if the process or the system crashes while the data is still sitting in +the operating system's page cache. It is disabled by default because forcing a +disk flush on every upload has a performance cost. Note that this syncs the +file contents only; if the new directory entry must survive a crash as well, +fsync the destination directory yourself. + #### `MemoryStorage` The memory storage engine stores the files in memory as `Buffer` objects. It @@ -287,20 +301,36 @@ memory storage is used. ### `limits` -An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods). +An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#exports). + +`limits` can also be a function that receives the request and returns such an +object. It is called once per request, before parsing starts, so limits can +depend on e.g. the authenticated user: + +```javascript +const upload = multer({ + limits: function (req) { + return { fileSize: req.user.maxUploadSize }; + }, +}); +``` + +Limits apply to the whole request; there is no per-file limit. To restrict +individual files by type or name, use `fileFilter` or a custom storage engine. The following integer values are available: -| Key | 描述 | Default | -| ------------------- | -------------------------------------------------------------------------- | --------- | -| `fieldNameSize` | Max field name size | 100 bytes | -| `fieldSize` | Max field value size (in bytes) | 1MB | -| `fields` | Max number of non-file fields | Infinity | -| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity | -| `files` | For multipart forms, the max number of file fields | Infinity | -| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity | -| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 | -| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinity | +| Key | 描述 | Default | +| ---------------------- | ------------------------------------------------------------------------------- | -------- | +| `fieldNameSize` | Max field name size | Infinity | +| `fieldSize` | Max field value size (in bytes) | 1MB | +| `fields` | Max number of non-file fields | Infinity | +| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity | +| `files` | For multipart forms, the max number of file fields | Infinity | +| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity | +| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 | +| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinity | +| `fieldArrayIndexLimit` | Max numeric array index accepted inside a field name (e.g. `a[3]` uses index 3) | Infinity | Specifying the limits can help protect your site against denial of service (DoS) attacks. @@ -325,6 +355,30 @@ function fileFilter(req, file, cb) { } ``` +### `streamHandler` + +By default Multer reads the request with `req.pipe(busboy)`. Some platforms +consume the request body before your handlers run, so there is nothing left to +pipe. Google Cloud Functions and Firebase Functions, for example, expose the +already-read body as `req.rawBody`. Provide a `streamHandler` to feed busboy +yourself in that case: + +```javascript +const upload = multer({ + storage: multer.memoryStorage(), + streamHandler: function (req, busboy) { + if (req.rawBody) { + busboy.end(req.rawBody); + } else { + req.pipe(busboy); + } + }, +}); +``` + +The function receives the request and the busboy instance and must write the +whole multipart body to busboy and end it. + ## Security Specifying the [limits](#limits) can help protect your site against denial of service (DoS) attacks. The following limits are recommended for most applications: @@ -333,15 +387,21 @@ Specifying the [limits](#limits) can help protect your site against denial of se - `files` -- set to the maximum number of files per request - `fields` -- set to the maximum number of text fields per request - `fieldNestingDepth` -- set to the minimum depth your field names require (e.g. `3` for `a[b][c]`) +- `fieldArrayIndexLimit` -- set to the largest array index your field names require (e.g. `100` for `a[99]`) ## Error handling When encountering an error, Multer will delegate the error to Express. You can -display a nice error page using [the standard express way](/guide/error-handling). +display a nice error page using [the standard express way](/guide/error-handling/). If you want to catch errors specifically from Multer, you can call the middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`). +Multer errors carry a `code` (e.g. `LIMIT_FILE_SIZE`) and, when the error concerns +a specific field, its name in `field`. Errors about a specific file +(`LIMIT_FILE_SIZE`, `LIMIT_UNEXPECTED_FILE`) also expose the client-supplied file +name in `filename`; treat it as untrusted input, like `file.originalname`. + ```javascript const multer = require('multer'); const upload = multer().single('avatar'); diff --git a/src/content/pages/zh-cn/resources/middleware/serve-index.mdx b/src/content/pages/zh-cn/resources/middleware/serve-index.mdx index 45f7b38d7b..9b3298dab5 100644 --- a/src/content/pages/zh-cn/resources/middleware/serve-index.mdx +++ b/src/content/pages/zh-cn/resources/middleware/serve-index.mdx @@ -39,7 +39,7 @@ var serveIndex = require('serve-index'); ### serveIndex(path, options) -Returns middlware that serves an index of the directory in the given `path`. +Returns middleware that serves an index of the directory in the given `path`. The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir` with a `path` of `'public'` will look at `'public/some/dir'`. If you are using @@ -150,7 +150,7 @@ app.listen(3000); ## License [MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). The [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) icons -are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20251120154741/http://www.famfamfam.com/). +are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20230109095739/http://www.famfamfam.com/). [appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index [downloads-url]: https://npmjs.org/package/serve-index diff --git a/src/content/pages/zh-cn/resources/middleware/session.mdx b/src/content/pages/zh-cn/resources/middleware/session.mdx index d3d1d197e5..51b99671a4 100644 --- a/src/content/pages/zh-cn/resources/middleware/session.mdx +++ b/src/content/pages/zh-cn/resources/middleware/session.mdx @@ -127,7 +127,7 @@ defined in the object is what is used. ##### cookie.partitioned -Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](https://github.com/expressjs/session/blob/HEAD/rfc-cutler-httpbis-partitioned-cookies) +Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`][rfc-cutler-httpbis-partitioned-cookies] attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not. By default, the `Partitioned` attribute is not set. @@ -140,6 +140,12 @@ More information about can be found in [the proposal](https://github.com/privacy Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which is the root path of the domain. +Since 1.19.1, path matching follows [RFC 6265 section 5.1.4][rfc-6265-5.1.4]. This means +the session middleware will only activate when the request path is an exact match or falls +under a segment boundary of the cookie path. For example, a cookie path of `/admin` will +match `/admin` and `/admin/users` but will **not** match `/administrator`. Prior versions +used a simple prefix check that did not enforce segment boundaries. + ##### cookie.priority Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1]. @@ -1003,6 +1009,7 @@ On Windows, use the corresponding command; [MIT](https://github.com/expressjs/session/blob/HEAD/LICENSE) +[rfc-6265-5.1.4]: https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 [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-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 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..57f63ddd2f --- /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 9b405a9d94..5bf3c4a28e 100644 --- a/src/content/pages/zh-tw/advanced/best-practice-security.mdx +++ b/src/content/pages/zh-tw/advanced/best-practice-security.mdx @@ -48,7 +48,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) { @@ -286,7 +286,7 @@ $ snyk test Keep an eye out for [GitHub Advisory Database](https://github.com/advisories?query=ecosystem%3Anpm) or [Snyk](https://security.snyk.io/vuln/npm) advisories that may affect Express or other modules that your app uses. In general, these databases are excellent resources for knowledge and tools about Node security. -Finally, Express apps—like any other web apps—can be vulnerable to a variety of web-based attacks. Familiarize yourself with known [web vulnerabilities](https://www.owasp.org/www-project-top-ten/) and take precautions to avoid them. +Finally, Express apps—like any other web apps—can be vulnerable to a variety of web-based attacks. Familiarize yourself with known [web vulnerabilities](https://owasp.org/www-project-top-ten/) and take precautions to avoid them. ## Additional considerations @@ -294,8 +294,8 @@ Here are some further recommendations from the excellent [Node.js Security Check - Always filter and sanitize user input to protect against cross-site scripting (XSS) and command injection attacks. - Defend against SQL injection attacks by using parameterized queries or prepared statements. -- Use the open-source [sqlmap](http://sqlmap.org/) tool to detect SQL injection vulnerabilities in your app. +- Use the open-source [sqlmap](https://sqlmap.org/) tool to detect SQL injection vulnerabilities in your app. - Use the [nmap](https://nmap.org/) and [sslyze](https://github.com/nabla-c0d3/sslyze) tools to test the configuration of your SSL ciphers, keys, and renegotiation as well as the validity of your certificate. -- Use [safe-regex](https://www.npmjs.com/package/safe-regex) to ensure your regular expressions are not susceptible to [regular expression denial of service](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) attacks. +- Use [safe-regex](https://www.npmjs.com/package/safe-regex) to ensure your regular expressions are not susceptible to [regular expression denial of service](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) attacks. -[helmet]: https://helmetjs.github.io/ +[helmet]: https://helmet.js.org/ 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/guide/migrating-4.mdx b/src/content/pages/zh-tw/guide/migrating-4.mdx index acd2fb1488..c27097bb43 100644 --- a/src/content/pages/zh-tw/guide/migrating-4.mdx +++ b/src/content/pages/zh-tw/guide/migrating-4.mdx @@ -43,133 +43,23 @@ middleware that is required to run your app. Simply follow these steps: The following table lists Express 3 middleware and their counterparts in Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Express 3Express 4
- express.bodyParser - - body-parser + - multer -
- express.compress - - compression -
- express.cookieSession - - cookie-session -
- express.cookieParser - - cookie-parser -
- express.logger - - morgan -
- express.session - - express-session -
- express.favicon - - serve-favicon -
- express.responseTime - - response-time -
- express.errorHandler - - errorhandler -
- express.methodOverride - - method-override -
- express.timeout - - connect-timeout -
- express.vhost - - vhost -
- express.csrf - - csurf -
- express.directory - - serve-index -
- express.static - - serve-static -
+| Express 3 | Express 4 | +| ------------------------ | ------------------------------------------------------------------------------------------------------- | +| `express.bodyParser` | [body-parser](https://github.com/expressjs/body-parser) + [multer](https://github.com/expressjs/multer) | +| `express.compress` | [compression](https://github.com/expressjs/compression) | +| `express.cookieSession` | [cookie-session](https://github.com/expressjs/cookie-session) | +| `express.cookieParser` | [cookie-parser](https://github.com/expressjs/cookie-parser) | +| `express.logger` | [morgan](https://github.com/expressjs/morgan) | +| `express.session` | [express-session](https://github.com/expressjs/session) | +| `express.favicon` | [serve-favicon](https://github.com/expressjs/serve-favicon) | +| `express.responseTime` | [response-time](https://github.com/expressjs/response-time) | +| `express.errorHandler` | [errorhandler](https://github.com/expressjs/errorhandler) | +| `express.methodOverride` | [method-override](https://github.com/expressjs/method-override) | +| `express.timeout` | [connect-timeout](https://github.com/expressjs/timeout) | +| `express.vhost` | [vhost](https://github.com/expressjs/vhost) | +| `express.csrf` | [csurf](https://github.com/expressjs/csurf) | +| `express.directory` | [serve-index](https://github.com/expressjs/serve-index) | +| `express.static` | [serve-static](https://github.com/expressjs/serve-static) | Here is the [complete list](https://github.com/senchalabs/connect#middleware) of Express 4 middleware. @@ -305,78 +195,21 @@ middleware that is specific to the route. The following table lists other small but important changes in Express 4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ObjectDescription
Node.jsExpress 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x.
`http.createServer()` - The `http` module is no longer needed, unless you need to directly work with it - (socket.io/SPDY/HTTPS). The app can be started by using the `app.listen()` function. -
`app.configure()` - The `app.configure()` function has been removed. Use the `process.env.NODE_ENV` or - `app.get('env')` function to detect the environment and configure the app accordingly. -
`json spaces` - The `json spaces` application property is disabled by default in Express 4. -
`req.accepted()` - Use `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, and - `req.acceptsLanguages()`. -
`res.location()`No longer resolves relative URLs.
`req.params`Was an array; now an object.
`res.locals`Was a function; now an object.
`res.headerSent`Changed to `res.headersSent`.
`app.route`Now available as `app.mountpath`.
`res.on('header')`Removed.
`res.charset`Removed.
`res.setHeader('Set-Cookie', val)` - Functionality is now limited to setting the basic cookie value. Use `res.cookie()` for added - functionality. -
+| Object | Description | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Node.js | Express 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x. | +| `http.createServer()` | The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). The app can be started by using the `app.listen()` function. | +| `app.configure()` | The `app.configure()` function has been removed. Use the `process.env.NODE_ENV` or `app.get('env')` function to detect the environment and configure the app accordingly. | +| `json spaces` | The `json spaces` application property is disabled by default in Express 4. | +| `req.accepted()` | Use `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, and `req.acceptsLanguages()`. | +| `res.location()` | No longer resolves relative URLs. | +| `req.params` | Was an array; now an object. | +| `res.locals` | Was a function; now an object. | +| `res.headerSent` | Changed to `res.headersSent`. | +| `app.route` | Now available as `app.mountpath`. | +| `res.on('header')` | Removed. | +| `res.charset` | Removed. | +| `res.setHeader('Set-Cookie', val)` | Functionality is now limited to setting the basic cookie value. Use `res.cookie()` for added functionality. | ## Example app migration diff --git a/src/content/pages/zh-tw/resources/middleware/body-parser.mdx b/src/content/pages/zh-tw/resources/middleware/body-parser.mdx index eec2e8a5d2..3547c52f26 100644 --- a/src/content/pages/zh-tw/resources/middleware/body-parser.mdx +++ b/src/content/pages/zh-tw/resources/middleware/body-parser.mdx @@ -44,6 +44,10 @@ This module provides the following parsers: - [Text body parser](#bodyparsertextoptions) - [URL-encoded form body parser](#bodyparserurlencodedoptions) +All parsers support automatic inflation of `gzip`, `br` (brotli), `deflate` +and `zstd` encodings. `zstd` is available in Node.js `^22.15.0` and +`>=23.8.0`. + Other body parsers you might be interested in: - [body](https://www.npmjs.com/package/body#readme) @@ -85,8 +89,7 @@ The various errors returned by this module are described in the Returns middleware that only parses `json` and only looks at requests where the `Content-Type` header matches the `type` option. This parser accepts any -Unicode encoding of the body and supports automatic inflation of `gzip`, -`br` (brotli) and `deflate` encodings. +Unicode encoding of the body. A new `body` object containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). @@ -146,9 +149,7 @@ encoding of the request. The parsing can be aborted by throwing an error. ### bodyParser.raw([options]) Returns middleware that parses all bodies as a `Buffer` and only looks at -requests where the `Content-Type` header matches the `type` option. This -parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate` -encodings. +requests where the `Content-Type` header matches the `type` option. A new `body` object containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). This will be a `Buffer` object @@ -194,9 +195,7 @@ encoding of the request. The parsing can be aborted by throwing an error. ### bodyParser.text([options]) Returns middleware that parses all bodies as a string and only looks at -requests where the `Content-Type` header matches the `type` option. This -parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate` -encodings. +requests where the `Content-Type` header matches the `type` option. A new `body` string containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). This will be a string of the @@ -247,8 +246,7 @@ encoding of the request. The parsing can be aborted by throwing an error. Returns middleware that only parses `urlencoded` bodies and only looks at requests where the `Content-Type` header matches the `type` option. This -parser accepts only UTF-8 and ISO-8859-1 encodings of the body and supports -automatic inflation of `gzip`, `br` (brotli) and `deflate` encodings. +parser accepts only UTF-8 and ISO-8859-1 encodings of the body. A new `body` object containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). This object will contain @@ -358,7 +356,7 @@ the entity value that failed parsing. ### entity verify failed This error will occur when the request contained an entity that could not be -failed verification by the defined `verify` option. The `status` property is +verified by the defined `verify` option. The `status` property is set to `403`, the `type` property is set to `'entity.verify.failed'`, and the `body` property is set to the entity value that failed verification. diff --git a/src/content/pages/zh-tw/resources/middleware/compression.mdx b/src/content/pages/zh-tw/resources/middleware/compression.mdx index 162d32c2c2..be10551790 100644 --- a/src/content/pages/zh-tw/resources/middleware/compression.mdx +++ b/src/content/pages/zh-tw/resources/middleware/compression.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -21,13 +21,13 @@ The following compression codings are supported: - gzip - br (brotli) -**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0. +**Note** Brotli is available in all currently supported Node.js LTS versions (v18+). ## Install This is a [Node.js](https://nodejs.org/en/) module available through the [npm registry](https://www.npmjs.com/). Installation is done using the -[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): +[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally): @@ -304,7 +304,7 @@ The Express.js project welcomes all constructive contributions. Contributions ta from code for bug fixes and enhancements, to additions and fixes to documentation, additional tests, triaging incoming pull requests and issues, and more! -See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing. +See the [Contributing Guide](https://github.com/expressjs/.github/blob/HEAD/CONTRIBUTING.md) for more technical details on contributing. ## License diff --git a/src/content/pages/zh-tw/resources/middleware/cookie-session.mdx b/src/content/pages/zh-tw/resources/middleware/cookie-session.mdx index d9db6b0052..d250082180 100644 --- a/src/content/pages/zh-tw/resources/middleware/cookie-session.mdx +++ b/src/content/pages/zh-tw/resources/middleware/cookie-session.mdx @@ -124,7 +124,7 @@ The options can also contain any of the following (for the full list, see - `partitioned`: a boolean indicating whether to partition the cookie in Chrome for the [CHIPS Update](https://developers.google.com/privacy-sandbox/3pcd/chips) (`false` by default). If this is true, Cookies from embedded sites will be partitioned and only readable from the same top level site from which it was created. - `priority`: a string indicating the cookie priority. This can be set to `'low'`, `'medium'`, or `'high'`. - `sameSite`: a boolean or string indicating whether the cookie is a "same site" cookie (`false` by default). This can be set to `'strict'`, `'lax'`, `'none'`, or `true` (which maps to `'strict'`). -- `secure`: a boolean indicating whether the cookie is only to be sent over HTTPS (`false` by default for HTTP, `true` by default for HTTPS). If this is set to `true` and Node.js is not directly over a TLS connection, be sure to read how to [setup Express behind proxies](/guide/behind-proxies) or the cookie may not ever set correctly. +- `secure`: a boolean indicating whether the cookie is only to be sent over HTTPS (`false` by default for HTTP, `true` by default for HTTPS). If this is set to `true` and Node.js is not directly over a TLS connection, be sure to read how to [setup Express behind proxies](/guide/behind-proxies/) or the cookie may not ever set correctly. - `httpOnly`: a boolean indicating whether the cookie is only to be sent over HTTP(S), and not made available to client JavaScript (`true` by default). - `signed`: a boolean indicating whether the cookie is to be signed (`true` by default). - `overwrite`: a boolean indicating whether to overwrite previously set cookies of the same name (`true` by default). diff --git a/src/content/pages/zh-tw/resources/middleware/morgan.mdx b/src/content/pages/zh-tw/resources/middleware/morgan.mdx index bbf752df98..d4cffce323 100644 --- a/src/content/pages/zh-tw/resources/middleware/morgan.mdx +++ b/src/content/pages/zh-tw/resources/middleware/morgan.mdx @@ -8,14 +8,14 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; HTTP request logger middleware for node.js -> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. +> Named after [Dexter](https://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. ## Installation @@ -35,6 +35,16 @@ This is a [Node.js](https://nodejs.org/en/) module available through the ## API +For ES Modules: + +{/* eslint-disable no-unused-vars */} + +```js +import morgan from 'morgan'; +``` + +For CommonJS: + {/* eslint-disable no-unused-vars */} ```js @@ -78,10 +88,12 @@ morgan(function (tokens, req, res) { tokens.method(req, res), tokens.url(req, res), tokens.status(req, res), - tokens.res(req, res, 'content-length'), '-', - tokens['response-time'](https://github.com/expressjs/morgan/blob/HEAD/req, res), 'ms' - ].join(' ') -}) + tokens.res(req, res, 'content-length'), + '-', + tokens['response-time'](req, res), + 'ms', + ].join(' '); +}); ``` #### Options @@ -90,7 +102,7 @@ Morgan accepts these properties in the options object. ##### immediate -Write log line on request instead of response. This means that a requests will +Write log line on request instead of response. This means that requests will be logged even if the server crashes, _but data from the response (like the response code, content length, etc.) cannot be logged_. @@ -114,6 +126,33 @@ morgan('combined', { Output stream for writing log lines, defaults to `process.stdout`. +If the stream is in object mode (`stream.writableObjectMode` is `true`) and the +format function returns an object, the object is written to the stream as-is, +without a trailing newline. This allows passing structured log entries to +loggers that accept objects: + +{/* eslint-disable no-undef */} + +```js +morgan( + function (tokens, req, res) { + return { + method: tokens.method(req, res), + url: tokens.url(req, res), + status: Number(tokens.status(req, res)), + }; + }, + { + stream: { + writableObjectMode: true, + write: function (entry) { + // entry is the object returned by the format function + }, + }, + } +); +``` + #### Predefined Formats There are various pre-defined formats provided: @@ -151,6 +190,11 @@ for information codes. GET /dev 200 0.224 ms - 2 ``` +Coloring is disabled when the [`NO_COLOR`](https://no-color.org) environment +variable is set to any non-empty value, in which case the output above is +written without any escape sequences. The variable is read once, when `morgan` +is first required. + ##### short Shorter than default, also including response time. @@ -192,7 +236,7 @@ token definition. The token function is expected to be called with the arguments `req` and `res`, representing the HTTP request and HTTP response. Additionally, the token can accept further arguments of -it's choosing to customize behavior. +its choosing to customize behavior. ##### :date[format] @@ -218,7 +262,7 @@ The process ID of the Node.js process handling the request. ##### -The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer. +The Referrer header of the request. This will use the standard mis-spelled Referer header if it exists, otherwise Referrer. ##### :remote-addr @@ -264,7 +308,7 @@ include on the number, defaulting to `3`, which provides microsecond precision. ##### -The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`. +The URL of the request. This will use `req.originalUrl` if it exists, otherwise `req.url`. ##### :user-agent @@ -274,12 +318,12 @@ The contents of the User-Agent header of the request. Compile a format string into a `format` function for use by `morgan`. A format string is a string that represents a single log line and can utilize token syntax. -Tokens are references by `:token-name`. If tokens accept arguments, they can +Tokens are referenced by `:token-name`. If tokens accept arguments, they can be passed using `[]`, for example: `:token-name[pretty]` would pass the string `'pretty'` as an argument to the token `token-name`. The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and -`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and +`res`, where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res` is the HTTP response. The function will return a string that will be the log line, or `undefined` / `null` to skip logging. @@ -290,7 +334,7 @@ advanced uses, this compile function is directly available. ### express/connect -Sample app that will log all request in the Apache combined format to STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var express = require('express'); @@ -307,7 +351,7 @@ app.get('/', function (req, res) { ### vanilla http server -Sample app that will log all request in the Apache combined format to STDOUT +Sample app that will log all requests in the Apache combined format to STDOUT ```js var finalhandler = require('finalhandler'); @@ -431,7 +475,7 @@ Sample app that will use custom token formats. This adds an ID to all requests a ```js var express = require('express'); var morgan = require('morgan'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); morgan.token('id', function getId(req) { return req.id; diff --git a/src/content/pages/zh-tw/resources/middleware/multer.mdx b/src/content/pages/zh-tw/resources/middleware/multer.mdx index f4c9dd14fb..d32246802f 100644 --- a/src/content/pages/zh-tw/resources/middleware/multer.mdx +++ b/src/content/pages/zh-tw/resources/middleware/multer.mdx @@ -8,7 +8,7 @@ import Alert from '@components/primitives/Alert/Alert.astro'; import PackageManagerCommand from '@components/patterns/PackageManagerCommand/PackageManagerCommand.astro'; @@ -18,23 +18,6 @@ on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency. **NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`). -## Translations - -This README is also available in other languages: - -| | | -| ------------------------------------------------------------------------------ | --------------- | -| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic | -| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese | -| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French | -| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean | -| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) | -| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian | -| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish | -| [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) | Turkish | - ## Installation @@ -130,23 +113,26 @@ app.post('/stats', upload.single('uploaded_file'), function (req, res) { }); ``` +Complete client-side and server-side examples (browser `FormData` uploads of a +blob and of an image) are in the [`examples/`](https://github.com/expressjs/multer/blob/HEAD/examples/) folder. + ## API ### File information Each file contains the following information: -| Key | Description | Note | -| -------------- | --------------------------------------------- | --------------- | -| `fieldname` | Field name specified in the form | | -| `originalname` | Name of the file on the user's computer | | -| `encoding` | Encoding type of the file | | -| `mimetype` | Mime type of the file | | -| `size` | Size of the file in bytes | | -| `destination` | The folder to which the file has been saved | `DiskStorage` | -| `filename` | The name of the file within the `destination` | `DiskStorage` | -| `path` | The full path to the uploaded file | `DiskStorage` | -| `buffer` | A `Buffer` of the entire file | `MemoryStorage` | +| Key | Description | Note | +| -------------- | ----------------------------------------------------------------------------------- | --------------- | +| `fieldname` | Field name specified in the form | | +| `originalname` | Name of the file on the user's computer, or the full path when `preservePath: true` | | +| `encoding` | Encoding type of the file | | +| `mimetype` | Mime type of the file | | +| `size` | Size of the file in bytes | | +| `destination` | The folder to which the file has been saved | `DiskStorage` | +| `filename` | The name of the file within the `destination` | `DiskStorage` | +| `path` | The full path to the uploaded file | `DiskStorage` | +| `buffer` | A `Buffer` of the entire file | `MemoryStorage` | ### `multer(opts)` @@ -161,11 +147,15 @@ The following are the options that can be passed to Multer. | Key | Description | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `defCharset` | Default character set to use for text field values that do not declare one. Default: `'utf8'` | +| `defParamCharset` | Default character set to use for values of part header parameters (e.g. filename) that are not extended parameters (that contain an explicit charset). Default: `'latin1'` | | `dest` or `storage` | Where to store the files | | `fileFilter` | Function to control which files are accepted | +| `fileHwm` | `highWaterMark` of each file stream (`file.stream`). Default: busboy's default | +| `highWaterMark` | `highWaterMark` of the multipart parser stream. Default: busboy's default | | `limits` | Limits of the uploaded data | -| `preservePath` | Keep the full path of files instead of just the base name | -| `defParamCharset` | Default character set to use for values of part header parameters (e.g. filename) that are not extended parameters (that contain an explicit charset). Default: `'latin1'` | +| `preservePath` | Keep the full client-supplied path in `file.originalname` instead of just the base name | +| `streamHandler` | Function that feeds the request body to busboy; defaults to `req.pipe(busboy)` | In an average web app, only `dest` might be required, and configured as shown in the following example. @@ -174,6 +164,14 @@ the following example. const upload = multer({ dest: 'uploads/' }); ``` +When `preservePath` is enabled, Multer passes the incoming filename through with +any path segments provided by the client. This is exposed as `file.originalname`; +it does not change the destination folder, create directories, or sanitize the +path for you. `file.originalname` is always client-supplied and should be treated +as untrusted; with `preservePath` it additionally contains the path segments the +client sent. Normalize or validate it before using it in a custom `filename` or +storage engine. + If you want more control over your uploads, you'll want to use the `storage` option instead of `dest`. Multer ships with storage engines `DiskStorage` and `MemoryStorage`; More engines are available from third parties. @@ -189,6 +187,9 @@ Accept an array of files, all with the name `fieldname`. Optionally error out if more than `maxCount` files are uploaded. The array of files will be stored in `req.files`. +Files skipped by `fileFilter` do not count towards `maxCount`. Use +`limits.files` to bound how many files are read from a request. + #### `.fields(fields)` Accept a mix of files, specified by `fields`. An object with arrays of files @@ -207,11 +208,11 @@ Example: #### `.none()` Accept only text fields. If any file upload is made, error with code -"LIMIT_UNEXPECTED_FILE" will be issued. +`LIMIT_UNEXPECTED_FILE` will be issued. #### `.any()` -Accepts all files that comes over the wire. An array of files will be stored in +Accepts all files that come over the wire. An array of files will be stored in `req.files`. **WARNING:** Make sure that you always handle the files that a user uploads. @@ -226,21 +227,26 @@ where you are handling the uploaded files. The disk storage engine gives you full control on storing files to disk. ```javascript +const crypto = require('crypto'); + const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/tmp/my-uploads'); }, filename: function (req, file, cb) { - const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); - cb(null, file.fieldname + '-' + uniqueSuffix); + crypto.randomBytes(16, function (err, raw) { + if (err) return cb(err); + cb(null, file.fieldname + '-' + raw.toString('hex')); + }); }, }); const upload = multer({ storage: storage }); ``` -There are two options available, `destination` and `filename`. They are both -functions that determine where the file should be stored. +There are three options available: `destination`, `filename` and `flush`. All of +them except `flush` are functions that determine where the file should be +stored. `destination` is used to determine within which folder the uploaded files should be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no @@ -268,6 +274,14 @@ For understanding the calling convention used in the callback (needing to pass null as the first param), refer to [Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors) +`flush` is an optional boolean. When set to `true`, the file data is flushed to +disk with an `fsync` call before the upload handler runs, which prevents data +loss if the process or the system crashes while the data is still sitting in +the operating system's page cache. It is disabled by default because forcing a +disk flush on every upload has a performance cost. Note that this syncs the +file contents only; if the new directory entry must survive a crash as well, +fsync the destination directory yourself. + #### `MemoryStorage` The memory storage engine stores the files in memory as `Buffer` objects. It @@ -287,20 +301,36 @@ memory storage is used. ### `limits` -An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods). +An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#exports). + +`limits` can also be a function that receives the request and returns such an +object. It is called once per request, before parsing starts, so limits can +depend on e.g. the authenticated user: + +```javascript +const upload = multer({ + limits: function (req) { + return { fileSize: req.user.maxUploadSize }; + }, +}); +``` + +Limits apply to the whole request; there is no per-file limit. To restrict +individual files by type or name, use `fileFilter` or a custom storage engine. The following integer values are available: -| Key | Description | Default | -| ------------------- | -------------------------------------------------------------------------- | --------- | -| `fieldNameSize` | Max field name size | 100 bytes | -| `fieldSize` | Max field value size (in bytes) | 1MB | -| `fields` | Max number of non-file fields | Infinity | -| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity | -| `files` | For multipart forms, the max number of file fields | Infinity | -| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity | -| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 | -| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinity | +| Key | Description | Default | +| ---------------------- | ------------------------------------------------------------------------------- | -------- | +| `fieldNameSize` | Max field name size | Infinity | +| `fieldSize` | Max field value size (in bytes) | 1MB | +| `fields` | Max number of non-file fields | Infinity | +| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity | +| `files` | For multipart forms, the max number of file fields | Infinity | +| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity | +| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 | +| `fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinity | +| `fieldArrayIndexLimit` | Max numeric array index accepted inside a field name (e.g. `a[3]` uses index 3) | Infinity | Specifying the limits can help protect your site against denial of service (DoS) attacks. @@ -325,6 +355,30 @@ function fileFilter(req, file, cb) { } ``` +### `streamHandler` + +By default Multer reads the request with `req.pipe(busboy)`. Some platforms +consume the request body before your handlers run, so there is nothing left to +pipe. Google Cloud Functions and Firebase Functions, for example, expose the +already-read body as `req.rawBody`. Provide a `streamHandler` to feed busboy +yourself in that case: + +```javascript +const upload = multer({ + storage: multer.memoryStorage(), + streamHandler: function (req, busboy) { + if (req.rawBody) { + busboy.end(req.rawBody); + } else { + req.pipe(busboy); + } + }, +}); +``` + +The function receives the request and the busboy instance and must write the +whole multipart body to busboy and end it. + ## Security Specifying the [limits](#limits) can help protect your site against denial of service (DoS) attacks. The following limits are recommended for most applications: @@ -333,15 +387,21 @@ Specifying the [limits](#limits) can help protect your site against denial of se - `files` -- set to the maximum number of files per request - `fields` -- set to the maximum number of text fields per request - `fieldNestingDepth` -- set to the minimum depth your field names require (e.g. `3` for `a[b][c]`) +- `fieldArrayIndexLimit` -- set to the largest array index your field names require (e.g. `100` for `a[99]`) ## Error handling When encountering an error, Multer will delegate the error to Express. You can -display a nice error page using [the standard express way](/guide/error-handling). +display a nice error page using [the standard express way](/guide/error-handling/). If you want to catch errors specifically from Multer, you can call the middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`). +Multer errors carry a `code` (e.g. `LIMIT_FILE_SIZE`) and, when the error concerns +a specific field, its name in `field`. Errors about a specific file +(`LIMIT_FILE_SIZE`, `LIMIT_UNEXPECTED_FILE`) also expose the client-supplied file +name in `filename`; treat it as untrusted input, like `file.originalname`. + ```javascript const multer = require('multer'); const upload = multer().single('avatar'); diff --git a/src/content/pages/zh-tw/resources/middleware/serve-index.mdx b/src/content/pages/zh-tw/resources/middleware/serve-index.mdx index 7b556879de..b96ac28c4e 100644 --- a/src/content/pages/zh-tw/resources/middleware/serve-index.mdx +++ b/src/content/pages/zh-tw/resources/middleware/serve-index.mdx @@ -39,7 +39,7 @@ var serveIndex = require('serve-index'); ### serveIndex(path, options) -Returns middlware that serves an index of the directory in the given `path`. +Returns middleware that serves an index of the directory in the given `path`. The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir` with a `path` of `'public'` will look at `'public/some/dir'`. If you are using @@ -150,7 +150,7 @@ app.listen(3000); ## License [MIT](https://github.com/expressjs/serve-index/blob/HEAD/LICENSE). The [Silk](https://web.archive.org/web/20230105212205/http://www.famfamfam.com/lab/icons/silk/) icons -are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20251120154741/http://www.famfamfam.com/). +are created by/copyright of [FAMFAMFAM](https://web.archive.org/web/20230109095739/http://www.famfamfam.com/). [appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index [downloads-url]: https://npmjs.org/package/serve-index diff --git a/src/content/pages/zh-tw/resources/middleware/session.mdx b/src/content/pages/zh-tw/resources/middleware/session.mdx index 65f97eac18..8c186a601c 100644 --- a/src/content/pages/zh-tw/resources/middleware/session.mdx +++ b/src/content/pages/zh-tw/resources/middleware/session.mdx @@ -127,7 +127,7 @@ defined in the object is what is used. ##### cookie.partitioned -Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](https://github.com/expressjs/session/blob/HEAD/rfc-cutler-httpbis-partitioned-cookies) +Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`][rfc-cutler-httpbis-partitioned-cookies] attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not. By default, the `Partitioned` attribute is not set. @@ -140,6 +140,12 @@ More information about can be found in [the proposal](https://github.com/privacy Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which is the root path of the domain. +Since 1.19.1, path matching follows [RFC 6265 section 5.1.4][rfc-6265-5.1.4]. This means +the session middleware will only activate when the request path is an exact match or falls +under a segment boundary of the cookie path. For example, a cookie path of `/admin` will +match `/admin` and `/admin/users` but will **not** match `/administrator`. Prior versions +used a simple prefix check that did not enforce segment boundaries. + ##### cookie.priority Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1]. @@ -1003,6 +1009,7 @@ On Windows, use the corresponding command; [MIT](https://github.com/expressjs/session/blob/HEAD/LICENSE) +[rfc-6265-5.1.4]: https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 [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-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 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)